Currently a function (by value) can be a template parameter:
template<int(f)(int)> struct X {
int callf() { return f(1); }
};
This is logical as template parameters are constexpr, so there is no need for a reference or pointer. Thus, for consistency, a function template template parameter, which is a subset of variable template template parameters should be allowed to be by value:
template<template<int A> int(f)(int)> struct Y {
int callf() { return f<1>(2); }
};
This is in contrast with template variables of function type, which must be references or pointers to the actual function:
template<int B> int tfun(int a) { return a + B; } // function template
template<int A> int(*ftpl)(int) = tfun<A>; // variable template of function pointer type.
Here the template variable ftpl has to have pointer or reference type (even if it is const or even constexpr). For consistency with non-template functions template parameters (as in the first snippet above) by value functions should be allowed as function template template parameters. This should be clear in the wording.
Currently a function (by value) can be a template parameter:
This is logical as template parameters are constexpr, so there is no need for a reference or pointer. Thus, for consistency, a function template template parameter, which is a subset of variable template template parameters should be allowed to be by value:
This is in contrast with template variables of function type, which must be references or pointers to the actual function:
Here the template variable ftpl has to have pointer or reference type (even if it is const or even constexpr). For consistency with non-template functions template parameters (as in the first snippet above) by value functions should be allowed as function template template parameters. This should be clear in the wording.