Reputation: 2271
Can someone please help me to understand why the following code does not compile:
template< typename T >
class A
{};
template< typename U >
class wrapper
{
public:
// cast operator
operator wrapper< A<void> > ()
{
return wrapper< A<void> >{};
}
};
template< typename T >
void foo( wrapper< A<T> > )
{}
int main()
{
foo( wrapper<void>{} );
}
error message:
t.cpp:24:7: error: no matching function for call to 'foo'
foo( wrapper<void>{} );
^~~
t.cpp:18:10: note: candidate template ignored: could not match 'A<type-parameter-0-0>' against 'void'
void foo( wrapper< A<T> > )
^
1 error generated.
and how to fix it?
I expected that wrapper<void>
is casted to wrapper< A<void >
using the cast operator of class wrapper
.
Upvotes: 2
Views: 140
Reputation: 8501
The problem is that foo
-s template deduction fails because the of the implicit cast.
foo
tries to deduce type Twrapper<void>
, A = wrapper<A<T>>
foo
has no possible way to deduce what A<T>
isSo, we have to help foo
deduce T.
Solution 1
Let foo
know what is T explicitly:
foo<void>( wrapper<void>{} );
Solution 2
Cast wrapper
to wrapper< A<void> >
explicitly to let foo
know what T is:
foo( static_cast< wrapper< A<void> > >(wrapper<void>{}) );
Upvotes: 3
Reputation: 7482
You can fix it by explicitly cast wrapper< void >
to wrapper< A<void> >
using static_cast
as shown in the following:
int main()
{
foo( static_cast< wrapper< A<void> > >(wrapper<void>{}) );
}
which compiles smoothly.
Note that template deduction does try to match the template parameters exactly without doing conversions. It means that if a cast is necessary in order to make things match exactly then the cast has to be explicit.
Upvotes: 3