【问题标题】:GCC: template previously defined errorGCC:模板先前定义的错误
【发布时间】:2016-07-13 09:29:57
【问题描述】:

我有以下代码可用于 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 上出现这个错误吗?

【问题讨论】:

  • 详细说明你想做什么。运算符的声明在哪里,是否在其他类中?这段代码的目的是什么 - 与一些现有的运算符成为朋友或定义新的朋友运算符或替换现有的运算符?
  • @user2807083 这两个定义在同一个类中。我使用这两个模板来格式化 HTTP 请求,如问题所示。

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


【解决方案1】:

解决方案是将第二个模板的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) 
{
  ...
}

【讨论】:

    【解决方案2】:

    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;
    }
    

    【讨论】:

    • 感谢您的回复。我正在使用 GCC 4.4.7 我已经单独尝试了您的示例,并且只有在启用时才有效:g++ -std=c++0x。无论如何,在我的项目上做同样的事情并不能解决错误。可能与在同一个 cpp 中定义了另一个具有相同参数列表的模板有关吗?我在我原来的问题中添加了这个。
    • @cristian 该模板有不同的名称,所以这不是原因。检查previously defined here 指向的行。如果它不存在于代码中,则可能会发生模板的隐式实例化并导致错误。如果可以,请张贴错误消息提到的行。
    • 唯一有错误的行是我帖子中的第 3 行(末尾标有“
    • @cristian 之前在这里定义的错误应该指向两行,第一个定义和导致错误的重新定义。稍微改变你的函数签名,比如,添加一些空格,这样你就可以看到两者之间的区别。简单示例:void fun(int a);void fun ( int a ); 您应该会看到错误消息的差异。
    • 哦....现在我明白了。谢谢你。我已经确定了另一个定义并在问题中添加了。这两者共同导致了冲突。我不明白这不适用于 GCC...
    猜你喜欢
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 2010-10-17
    • 2012-04-21
    • 2017-07-25
    • 1970-01-01
    相关资源
    最近更新 更多