Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't operator conversions implicitly called for templated functions? (C++)

I have the following code:

template <class T>
struct pointer
{
  operator pointer<const T>() const;
};


void f(pointer<const float>);

template <typename U>
void tf(pointer<const U>);

void g()
{
  pointer<float> ptr;
  f(ptr);
  tf(ptr);
}

When I compile the code with gcc 4.3.3 I get a message (aaa.cc:17: error: no matching function for call to ‘tf(pointer<float>&)’) indicating that the compiler called 'operator pointer<const T>' for the non-templated function f(), but didn't for the templated function tf(). Why and is there any workaround short of overloading tf() with a const and non-const version?

Thanks in advance for any help.

like image 217
John Gordon Avatar asked Apr 19 '10 17:04

John Gordon


2 Answers

The reason is that you don't get implicit type conversions during template deduction, it never gets to that point.

Consider:

template <typename T>
struct foo {};

template <typename U>
void bar(foo<U>)
{}

foo<int> f;
bar(f);

For that call to bar, the compiler can deduce that U is an int, and instantiate the function. However, consider:

template <typename U>
void bar(foo<const U>)
{}  // note  ^^^^

foo<int> f;
bar(f);

There is no U the compiler can deduce such that the type of foo matches the type of the parameter. Ergo, template instantiation fails. There is no chance for the conversion to happen.

like image 131
GManNickG Avatar answered Jan 30 '23 19:01

GManNickG


template <typename U>
void tf(pointer<const float>);

^ The compiler won't match a function call to this function unless you explicitly specify a parameter type at the function call, since you don't use the typename U as a function argument. I suspect you want to do something like:

template <typename U>
void tf(pointer<U>);
like image 41
Charles Salvia Avatar answered Jan 30 '23 20:01

Charles Salvia