void func1(int){} void func2(char){} template <typename T> void (*p)(T); // error p = func1; p = func2; Why cant we define a pointer like p?
You can do it like this:
template<class T> using p = void (*)(T); void f(int ); p<int> x = &f; C++14 actually allows variable templates, so your definition of the template p is valid.
However, p is a variable template, not a variable; in order to get an actual variable, you need to instantiate it with a particular type, like so:
p<int> = func1; p<char> = func2; p is a type, not a variable.p is a variable template.void (*)(int) or a void (*)(void).In your example, the variable p is able to be assigned objects of unrelated types (here, two incompatible function pointers). Such a dynamic change in apparent type is not supported by templates, which are strictly static (compile-time) constructs.
If you want to achieve such a type-shifting object, type erasure techniques must be applied. In that specific case, std::function looks like it could be of use to you, but you still need to decide on a fixed function signature (how would you call it otherwise ?).
Thanks to @SergeyA and @Brian 's help, I solved the problem and I edit my answer here.
template<typename T> void (*p)(T): in this case, p is a variable template(c++14). So we can use p like this:
p<int> = func1; p<char> = func2; template<class T> using p = void (*)(T): in this case, p is a kind of type(it's just like typedef but we cant use typedef for alias template). Meaning that we should use it like this:
p<int> x1 = func1; p<char> x2 = func2; Btw, both of them are template declaration, so we can't put them at any block scope.