Как я могу использовать специализированную специализацию в классах С++ и почему это не компилируется?
Я работаю над классом XmlWriter
, и я хотел бы иметь возможность выводить атрибуты или текст в большинстве стандартных форматов данных (строки, целые числа, числа с плавающей запятой и т.д.). Для этого я использую поток файлов.
Для типа данных bool
я хотел указать специализацию для шаблона, чтобы он выводил true
и false
вместо 1
и 0
.
Однако следующий код, похоже, не компилируется:
class XmlWriter {
private: /* ... */
public: /* ... */
template <typename T>
void writeText(T text) {
/* ... */
}
template <> // <-- error: explicit specialization in non-namespace scope 'class Strategy::IO::XmlWriter'
void writeText<bool> (bool text) { // <-- error: template-id 'writeText<>' in declaration of primary template
/* ... */
}
template <typename T>
void writeAttribute(std::string key, T value) { // <-- error: too many template-parameter-lists
/* ... */
}
template <> // <-- error: explicit specialization in non-namespace scope 'class Strategy::IO::XmlWriter'
void writeAttribute<bool> (std::string key, bool value) { // <-- error: variable or field 'writeAttribute' declared void; expected ';' before '<' token
/* ... */
}
}; // <-- expected ';' before '}' token
Я не понимаю, почему все эти ошибки, так как я использовал правильный синтаксис, представленный на разных сайтах в Интернете?
Я использую Cygwin GCC.
Ответы
Ответ 1
явная специализация в области без пространства имен 'class Strategy:: IO:: XmlWriter'
Попробуйте переместить специализацию в область пространства имен?
class XmlWriter {
private: /* ... */
public: /* ... */
template <typename T>
void writeText(T text) {
}
template <typename T>
void writeAttribute(std::string key, T value) {
}
};
template <>
void XmlWriter::writeText<bool> (bool text) {
}
template <>
void XmlWriter::writeAttribute<bool> (std::string key, bool value) {
}
Ответ 2
Вместо специализации вы можете просто перегрузить writeText()
и writeAttribute()
:
class XmlWriter {
private: /* ... */
public: /* ... */
template <typename T>
void writeText(T text) {}
void writeText(bool text) {}
template <typename T>
void writeAttribute(std::string key, T value) {}
void writeAttribute(std::string key, bool value) {}
};
Скомпилирован с g++ v4.6.1.
Ответ 3
Возможно, это просто из-за вашего упрощенного примера кода, но вам действительно не нужно использовать специализированную специализацию для этой проблемы. Перегрузка функций должна выполнять работу отлично. Поэтому вы можете переписать код немного следующим образом:
class XmlWriter
{
public:
template <typename T>
void writeText(T text) {
std::cout << "Text: " << text;
}
void writeText (bool text) {
std::cout << "Bool: " << text;
}
};
Ответ 4
Удалите специализированное объявление и в определении сделайте его inline:
class XmlWriter {
private: /* ... */
public: /* ... */
template <typename T>
void writeText(T text) {
}
template <typename T>
void writeAttribute(std::string key, T value) {
}
};
template <>
inline void XmlWriter::writeText<bool> (bool text) {
}
template <>
inline void XmlWriter::writeAttribute<bool> (std::string key, bool value) {
}