Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ conversion operator and overload resolution

Given this example, which includes a few overloads:

#include <iostream>

class T
{
   public:
      operator const wchar_t *(void) const
      {
         std::cout << "Conversion" << std::endl;
         return L"Testing";
      }
};

template <class Elem>
class A
{
};

template <class T>
void operator <<(A<T> &, const T *)
{
   std::cout << "1" << std::endl;
}

template <class T>
void operator <<(A<T> &, const void *)
{
   std::cout << "2" << std::endl;
}

int main(void)
{
   A<wchar_t> test;
   T          source;

   test << L"1";
   test << static_cast<const wchar_t *>(source);
   test << source;
}


And its output:

1
Conversion
1
Conversion
2


My question is - why is void operator <<(A<T> &, const void *) being called for the statement test << source;? Can anyone cite a specific part of the standard that covers this case?

like image 812
DOS Avatar asked Mar 24 '26 23:03

DOS


1 Answers

Because template argument deduction doesn't take user defined implicit conversions into account. The result is that when you wrote:

test << source;

, the compiler could not find a suitable T for the first function template; it is trying to find a T such that T const* has the same type as your T, which isn't possible. Argument deduction fails, and no instantiation of the template is added to the overload set. Since there's no template argument in the second parameter of the second function template, there's no argument deduction to fail, and the resulting instantiation becomes the only member of the overload set, and so ends up being chosen.

like image 78
James Kanze Avatar answered Mar 26 '26 11:03

James Kanze