c++ - template - Plantilla variable en la clase de plantilla-error inesperado(¿posible error?)
template<> c++ (2)
Teniendo:
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; }
No compila con clang ++ 3.6.
error: no se puede referir a la variable variable ''valor'' sin una lista de argumentos de plantilla
No compila con g ++ 5.2.
error: ''plantilla constexpr const T Valor :: valor'' no es una plantilla de función
(1) ideone
Compila tanto con clang ++ como con g ++.
struct Something
{
void x()
{
static_assert(Value::template value<int> == 0, "");
}
};
int main() { Something{}.x(); return 0; }
¿Por qué (0) no se compila?
Parece que el problema ocurre si se accede a la plantilla variable a través de un parámetro de plantilla (en este caso, TValue
). La definición de un alias de tipo para TValue
o el uso de la palabra clave typename
no soluciona el problema.
¿Que está pasando aqui?
Esto es definitivamente un error de gcc y clang en su tratamiento de plantillas variables como nombres dependientes. Envié gcc 67248 y clang 24473 .
Como solución por ahora, ambos compiladores admiten la forma antigua de hacer plantillas de variables, a saber, si agregas:
struct Value
{
template<class T>
static constexpr T value = 0;
template <typename T>
struct variable_template_ish {
static constexpr T value = Value::value<T>;
};
};
entonces lo siguiente compila:
template<typename TValue>
struct Something
{
void foo() {
static_assert(TValue::template variable_template_ish<int>::value == 0, "");
}
};
int main() {
Something<Value>{}.foo();
}
He tenido algunos dolores de cabeza antes al crear archivos de encabezado de clase de plantilla en c ++.
Asegúrese de que la implementación del static constexpr T value{0};
está en el mismo archivo de encabezado que la declaración.