Reputation: 57
I have following code:
void myfunc()
{
}
template <typename T>
void check()
{
}
template <typename T>
void checkT (T)
{
check<T>();
}
and so if I have in main function a call to checkT(myfunc)
then that compiles, but if I have check<myfunc>()
that doesn't work although it directly calls the first version. Can you please explain why it is so? The error is
error: no matching function for call to 'check()'
Thanks!
Upvotes: 1
Views: 107
Reputation: 158599
In the first instance checkT(myfunc)
it is able to deduce the type, checkT
is really identical to checkT( T value )
and so you are passing in value
and T
is being deduced. In the second case you are not supplying a type you can alter it like so to work:
check<decltype(myfunc)>() ;
you are actually supplying a value
where you need a type
in this case void(void)
.
Upvotes: 1
Reputation: 393739
This is because myfunc
is a value expression, not a type. You could do
check<decltype(myfunc)>();
though, or equivalently:
check<void(void)>();
See it live on http://liveworkspace.org/code/2ANEre$0
PS. In reply to the comment, I sense a bit of confusion between the function formal parameter and a template type parameter. Make it more explicit by writing:
template <typename T>
void checkT (T somevalue)
{
check<T>(); // note: somevalue is never used!
}
Upvotes: 3
Reputation: 96845
checkT(myfunc)
works because myfunc
is a value. But the second fails because it is not a type, which the template parameters require. For example,
void checkT(T)
is the same as
void checkT(T t)
so that means the function passed is an object of type T
. That is, t
is the object and T
is the type. In the template parameters of check
, it requires an explicit specification of the type, not the object. So thus passing in an object would raise a compilation error. Just like passing in the number 5 where the explicit type int
is expected.
You can use it as a type by wrapping it in a decltype
expression:
check<decltype(myfunc)>();
// ^^^^^^^^^^^^^^^^
Upvotes: 0