1

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!

1
  • To make things clear, give us an example of what you're explaining. Commented Mar 18, 2013 at 1:37

3 Answers 3

3

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! } 
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks! That worked. But my question is why it works when I call checkT(myfunc) which itself has call to check<myfunc>()?
Because it passes T, which is the type of the argument, not the value (as the template type argument)
I've tried to clarify in the answer, what seems to be the source of your confusion
So I guess what you are saying is that checkT(myfunc) and check<void(void)>() are the same? If so how can you explain output of liveworkspace.org/code/23fjAk$7 ?
Yes. And the difference you're are seeing is because of argument decay to function-pointer, unless you pass by reference: liveworkspace.org/code/2LhVWO$1
|
1

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

Comments

0

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)>(); // ^^^^^^^^^^^^^^^^ 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.