Ошибка компилятора g++ или код неисправности?: "определение шаблона без шаблона"
Как часть класса признаков для более крупной программы, я попытался создать статическую переменную класса, которая может иметь другое значение в зависимости от типа, с которым был создан экземпляр шаблона класса.
Я упростил соответствующий код, чтобы создать пример с голубыми костями, о котором я говорю:
#include <iostream>
#include <string>
#include <type_traits>
template <class T, class Enable = void>
struct Foo;
template <class T>
struct Foo<T,
typename std::enable_if<std::is_integral<T>::value>::type
>
{
static std::string message;
};
template <class T>
struct Foo<T,
typename std::enable_if<std::is_floating_point<T>::value>::type
>
{
static std::string message;
};
template <class T, class Enable>
std::string Foo<T, Enable>::message;
В GCC 4.6 это дает ошибку компилятора: template definition of non-template ‘std::string Foo<T, Enable>::message
. Проблема возникает из-за последних двух строк, где я просто определяю статическую переменную std::string Foo<T, Enable>::message
.
Я смущен, почему это происходит. Ошибка компилятора исчезает, если я опускаю последние две строки (но, конечно, это вызывает ошибки компоновщика.) Является ли это ошибкой компилятора с GCC?
Ответы
Ответ 1
Это работает только тогда, когда параметры вашего шаблона соответствуют частичной специализации:
template <class T>
std::string Foo<T,
typename std::enable_if<std::is_integral<T>::value>::type
>::message;
template <class T>
std::string Foo<T,
typename std::enable_if<std::is_floating_point<T>::value>::type
>::message;
Это указано в разделе 14.5.4.3 стандарта С++ 03. Идея состоит в том, что частичная специализация - это новый шаблон, а параметры шаблона членов, которые определены извне, должны соответствовать параметрам шаблона определения класса, чтобы он знал, к какому шаблону принадлежит член.
В вашем примере правило избегает определения члена сообщения для типов, которые не являются целыми или плавающими.