In the code below, why is a
in fn4
not considered a compile-time constant, when it is in fn1
, fn2
and fn3
?
Compiled with clang++ -std=c++17 file.cxx
template<typename T> constexpr T fn1(T a) {return a;}
template<typename T, T a> constexpr T fn2() {return a;}
template<typename T> constexpr T fn3(T a) {return fn1<T>(a);}
template<typename T> constexpr T fn4(T a) {return fn2<T, a>();}
int main() {
auto constexpr a = fn1<int>(1);
auto constexpr b = fn2<int, 2>();
auto constexpr c = fn3<int>(3);
auto constexpr d = fn4<int>(4);
return 0;
}
Output using clang-7.0:
file.cxx:9:56: error: no matching function for call to 'fn2'
template<typename T> constexpr T fn4(T a) {return fn2<T, a>();}
^~~~~~~~~
file.cxx:15:21: note: in instantiation of function template specialization 'fn4<int>' requested here
auto constexpr d = fn4<int>(4);
^
file.cxx:7:39: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'a'
template<typename T, T a> constexpr T fn2() {return a;}
^
file.cxx:15:17: error: constexpr variable 'd' must be initialized by a constant expression
auto constexpr d = fn4<int>(4);
^ ~~~~~~~~~~~
2 errors generated.