So I've got a templatized class which has a templatized static constexpr bool
. The setup boils down to this:
#include <type_traits>
template <typename T>
class A {
public:
template <typename U>
static constexpr bool same = std::is_same_v<T, U>;
};
template <typename T>
bool test() {
return A<T>::same<int>; // errors
}
int main() {
A<int>::same<int>; // compiles perfectly
test<int>(); // errors
}
When I access it with actual types like A<int>::same<int>
, it compiles just fine, but when I try to access it with a template type, as in the test()
function above, it errors. Here is the full list of errors:
constexpr_value.cpp: In function ‘bool test()’:
constexpr_value.cpp:12:21: error: expected primary-expression before ‘int’
12 | return A<T>::same<int>;
| ^~~
constexpr_value.cpp:12:21: error: expected ‘;’ before ‘int’
12 | return A<T>::same<int>;
| ^~~
| ;
constexpr_value.cpp:12:24: error: expected unqualified-id before ‘>’ token
12 | return A<T>::same<int>;
| ^
constexpr_value.cpp: In instantiation of ‘bool test() [with T = int]’:
constexpr_value.cpp:16:12: required from here
constexpr_value.cpp:12:16: error: ‘A<int>::same<U>’ missing template arguments
12 | return A<T>::same<int>;
| ^~~~
The first three errors are from the template itself, and they show up even when I don't use the test()
function at all, so it seems like the compiler is assuming A<T>::same<int>
is an invalid statement before even checking any specific T
s.
I don't understand these errors at all. Why does A<int>::same<int>
compile perfectly, but as soon as you use template types, it doesn't like it at all? I don't even know where to begin fixing this, because the errors tell me nothing. The only difference between compiling and not is using <T>
instead of <int>
, so is there something I can do with T
to tell the compiler that this is a valid statement?
CodePudding user response:
The template code is not equivalent to A<int>::same<int>
. This will also compile:
template <typename T>
bool test() {
return A<int>::same<int>;
}
Returning to the erroneous code. The latest GCC 12.1 would produce the hint in the warning:
constexpr_value.cpp: In function 'bool test()':
constexpr_value.cpp:12:16: warning: expected 'template' keyword before dependent template name [-Wmissing-template-keyword]
12 | return A<T>::same<int>; // errors
| ^~~~
As the warning message suggests the fix:
template <typename T>
bool test() {
return A<T>::template same<int>;
}
// ^^^^^^^^
See the hot question Where and why do I have to put the "template" and "typename" keywords? for more info.