Having:
struct Value
{
template<class T>
static constexpr T value{0};
};
(0) ideone
template<typename TValue>
struct Something
{
void x()
{
static_assert(TValue::template value<int> == 0, "");
}
};
int main() { Something<Value>{}.x(); return 0; }
Does not compile with clang++ 3.6.
error: cannot refer to variable template 'value' without a template argument list
Does not compile with g++ 5.2.
error: ‘template constexpr const T Value::value’ is not a function template
(1) ideone
Compiles with both clang++ and g++.
struct Something
{
void x()
{
static_assert(Value::template value<int> == 0, "");
}
};
int main() { Something{}.x(); return 0; }
Why does (0) fail to compile?
It seems that the issue occurs if the variable template is accessed through a template parameter (in this case, TValue
). Defining a type alias for TValue
or using the typename
keyword does not fix the issue.
What's going on here?
This is definitely a gcc and clang bug in their treatment of variable templates as dependent names. I submitted gcc 67248 and clang 24473.
As a workaround for now, both compilers support the old way of doing variable templates, namely if you added:
struct Value
{
template<class T>
static constexpr T value = 0;
template <typename T>
struct variable_template_ish {
static constexpr T value = Value::value<T>;
};
};
then the following compiles:
template<typename TValue>
struct Something
{
void foo() {
static_assert(TValue::template variable_template_ish<int>::value == 0, "");
}
};
int main() {
Something<Value>{}.foo();
}
I've had some headaches before when creating template class header files in c++.
Make sure you implementation of static constexpr T value{0};
is in the same header file as the declaration.
来源:https://stackoverflow.com/questions/32050119/variable-template-in-template-class-unexpected-error-possible-bug