John Gordon
John Gordon

Reputation: 2704

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.

Upvotes: 7

Views: 230

Answers (2)

GManNickG
GManNickG

Reputation: 504033

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.

Upvotes: 6

Charles Salvia
Charles Salvia

Reputation: 53309

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>);

Upvotes: 1

Related Questions