GCC:模板先前定义的错误

时间:2016-03-25 15:42:53

标签: c++ linux visual-studio gcc g++

我有以下代码使用Visual C ++ 10但不适用于Linux上的GCC:

class basic_format 
{
    ... 
    basic_format() : str_(), fmt_() {}
    ... 

    template <class ValueT>
    basic_format& operator%(const ValueT& x) 
    {
    ...
    }

    template <class Ch, class Tr>
    friend std::basic_ostream<Ch, Tr>& operator<<(
        std::basic_ostream<Ch, Tr>& sout, const basic_format<Ch, Tr>& f) 
    {
      ...
    }
    ...
}

使用:

query << basic_format<char_type>("%s %s HTTP/%.1f\r\n") % method % path % this->version();

编译器大叫:

Multiple markers at this line
    - ‘template<class Ch, class Tr> std::basic_ostream<_CharT, _Traits>& clx::operator<<(std::basic_ostream<_CharT, _Traits>&, const clx::basic_format<Ch, 
     Tr>&)’ previously defined here
    - redefinition of ‘template<class Ch, class Tr> std::basic_ostream<_CharT, _Traits>& clx::operator<<(std::basic_ostream<_CharT, _Traits>&, const 
     clx::basic_format<Ch, Tr>&)’

我正在使用GCC 4.4.7 我可以做些什么来避免在GCC上出现这个错误吗?

2 个答案:

答案 0 :(得分:0)

GCC 4.9.3,编译并正常工作:

#include <iostream>

template<class Ch = char, class Tr = std::char_traits<char>>
class basic_format
{
    template <class C, class T>
    friend std::basic_ostream<C, T>& operator<<(
            std::basic_ostream<C, T>& sout, const basic_format<C, T>& f)
    {
        return sout << "lol";
    }
};

int main()
{
    std::cout << basic_format<>() << std::endl;
}

答案 1 :(得分:0)

解决方法是将第二个模板的def放在没有“朋友”的类之外,只保留声明:

class basic_format 
{
    basic_format() : str_(), fmt_() {}

    template <class ValueT>
    basic_format& operator%(const ValueT& x) 
    {
    ...
    }

    template <class Ch, class Tr>
    friend std::basic_ostream<Ch, Tr>& operator<<(
        std::basic_ostream<Ch, Tr>& sout, const basic_format<Ch, Tr>& f);
}

template <class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(
    std::basic_ostream<Ch, Tr>& sout, const basic_format<Ch, Tr>& f) 
{
  ...
}