Как я могу использовать специализацию шаблона в классах c ++, и почему это не компилируется? - PullRequest
12 голосов
/ 28 февраля 2012

Я работаю над классом XmlWriter, и я хотел иметь возможность выводить атрибуты или текст в большинстве стандартных форматов данных (строки, целые числа, числа с плавающей запятой и т. Д.).Для этого я использую файловый поток.

Для типа данных bool я хотел указать специализацию для шаблона, чтобы он выводил true и false вместо * 1007.* и 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.

Ответы [ 4 ]

12 голосов
/ 28 февраля 2012

явная специализация в области отсутствия пространства имен '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) {
}
6 голосов
/ 28 февраля 2012

Вместо специализации вы можете просто перегрузить 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 голосов
/ 28 февраля 2012

Возможно, это просто из-за вашего упрощенного примера кода, но вам не нужно использовать специализацию шаблонов для этой проблемы. Перегрузка функций должна нормально работать. Таким образом, вы могли бы переписать ваш код примерно так:

class XmlWriter
{
public:
    template <typename T>
    void writeText(T text)  {
        std::cout << "Text: " << text;
    }

    void writeText (bool text) {  
        std::cout << "Bool: " << text;
    }
};
0 голосов
/ 04 апреля 2013

Удалите специальную декларацию и в определении сделайте ее встроенной:

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) {
}
...