【问题标题】:C++ overloading operator<< in a template class [duplicate]C ++重载运算符<<在模板类中[重复]
【发布时间】:2012-11-14 06:33:30
【问题描述】:

可能重复:
overloading friend operator<< for template class

我正在尝试为模板类重载运算符


最终(固定)代码:

template<class T>
class mytype
{
    T atr;
public:
    mytype();
    mytype(T);
    mytype(mytype&);
    T getAtr() const;
    T& operator=(const T&);
    template<class U> friend ostream& operator<<(ostream&,const mytype<U>&);
};

template<class T>
mytype<T>::mytype()
{
    atr=0;
}

template<class T>
mytype<T>::mytype(T value)
{
    atr=value;
}

template<class T>
mytype<T>::mytype(mytype& obj)
{
    atr=obj.getAtr();
}


template<class T>
T mytype<T>::getAtr() const
{
    return atr;
}

template<class T>
T& mytype<T>::operator=(const T &other)
{
    atr=other.getAtr();
    return *this;
}

template<class U>
ostream& operator<<(ostream& out,const mytype<U> &obj)
{
    out<<obj.getAtr();
    return out;
}

(全部在头文件中)


VS2012 错误:

1)

错误 1 ​​错误 LNK2019:函数 _wmain 中引用的未解析外部符号“public: __thiscall mytype::mytype(int)”(??0?$mytype@H@@QAE@H@Z)

2)

错误 2 错误 LNK2019:无法解析的外部符号“class std::basic_ostream > & __cdecl operator &,class mytype const &)” (??6@YAAAV?$basic_ostream@DU? $char_traits@D@std@@@std@@AAV01@ABV?$mytype@H@@@Z) 在函数_wmain中引用

3)

错误 3 error LNK1120: 2 unresolved externals


我的代码有什么问题?

【问题讨论】:

  • 不,Visual Studio 在 C++ 控制台应用程序中使用 _tmain 而不是 main
  • 每个 C++ 程序都需要有一个 main 函数作为入口点。您尝试在 Windows 中执行此操作的事实与您遇到的问题是正交的。
  • @JohnDibling,所以你的评论在这里毫无意义,因为它根本与问题无关。
  • 我不是 VS 专家,因为我在 linux 下工作,但我也知道 VS 使用 _tmain,因此本身不需要 main(),我不需要认为这是问题
  • 使用 Windows 特定的 _tmain 函数而不是标准规定的 main 函数会稍微混淆问题。不是每个人都熟悉 Windows,但假定 [C++] 标记中的每个人都在谈论标准 C++。您可能会对此处的特定于 Windows 的构造感到悲伤,这可能会妨碍获得实际答案。如果您遇到的问题并非特定于 Windows,我建议您将代码更改为使用标准构造。

标签: c++ class templates operator-overloading


【解决方案1】:

你告诉编译器期待一个免费的非模板函数:

friend ostream& operator<<(ostream&,const mytype<T>&);

...但是你定义了一个函数模板:

template<class T>
ostream& operator<<(ostream& out,const mytype<T> &obj)
{
    out<<obj.getAtr();
    return out;
}

告诉编译器期待一个函数模板:

template<class T> friend ostream& operator<<(ostream&,const mytype<T>&);

【讨论】:

  • 可能还会添加模板,通常驻留在类原型的标题中。不确定当所有内容都驻留在源中时效果如何。
  • +1 或者,内联定义非模板友元函数(在模板类定义内)
【解决方案2】:

似乎缺少构造函数的实现/定义。

【讨论】:

    【解决方案3】:

    编辑我现在看到问题已经更新并且构造函数已经定义。

    在这种情况下,您只需将构造函数定义放在标题中。 有些人这样做的另一种方法是定义一个 .inl(inline) 文件并将其包含在标题的底部。

    你声明构造函数

    mytype(T);
    

    但你从来没有真正开始定义它。

    编译器不会为上述构造函数创建默认主体,因为它不知道该怎么做。

    【讨论】:

      【解决方案4】:

      还需要在类的运算符声明中指定template&lt;class T&gt;

      template<class T>
      class mytype
      {
          T atr;
      public:
          ...
          T getAtr() const;
      
          template<class U>
          friend ostream& operator<<(ostream&,const mytype<U>&);
          ...
      };
      

      或者,在类中实现运算符:

      template<class T>
      class mytype
      {
          T atr;
      public:
          ...
          T getAtr() const;
      
          friend ostream& operator<<(ostream&,const mytype<T>&)
          {
              ...
          }
      
          ...
      };
      

      至于第一个错误,可能是因为你在源文件中实现了mytype的构造函数。对于模板类,您应该在类中实现所有方法(和构造函数等)。

      【讨论】:

      • @LightnessRacesinOrbit 当然可以,但是大多数人不会在类定义下面实现它们,他们只是在类中实现它们。
      • 这没有理由强制执行 :) 无论如何,我很想在该民意调查中看到您的数据 - 我和我认识的所有人都实现了离线功能,即使在标题中也是如此。
      猜你喜欢
      • 2021-09-19
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多