运营商LT;<重载调用打印功能的麻烦

时间:2012-02-23 07:17:16

标签: c++ operator-overloading ostream

好吧,我有点卡住试图超载<<我的模板类的运算符。要求是<< operator必须调用为此类定义的void print函数。

以下是模板标题中的重要内容:

template <class T>
class MyTemp {
public:
    MyTemp();           //constructor

    friend std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a);

    void print(std::ostream& os, char ofc = ' ') const;

这是我的打印功能,基本上它是一个矢量,并将最后一个元素打印到第一个:

    template <class T>
void Stack<T>::print(std::ostream& os, char ofc = ' ') const
{
    for ( int i = (fixstack.size()-1); i >= 0 ; --i)
    {
        os << fixstack[i] << ofc;
    }
}

以下是我如何拥有运算符&lt;&lt;重载:

    template <class T>
std::ostream& operator<< (std::ostream& os, const Stack<T>& a)
{
    // So here I need to call the a.print() function
}

但是我收到了“未解决的外部符号”错误。所以我想我有两个问题。第一个是修复上述错误的方法。第二,一旦修复了,我只需在&lt;&lt;&lt;&lt;&lt;&lt;&lt;超载?我知道它需要返回一个ostream。任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:2)

最简单的方法是将print公开(就像在你的例子中一样),这样操作员就不需要成为朋友了。

template <class T>
class MyTemp {
public:
    void print(std::ostream& os, char ofc = ' ') const;
};

template <class T>
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) {
    a.print(os);
    return os;
}

如果你确实需要它是私有的,那么你需要声明正确的模板特化是一个朋友 - 你的friend声明在周围的命名空间中声明一个非模板操作符,而不是模板。不幸的是,要使模板成为朋友,您需要事先声明它:

// Declare the templates first
template <class T> class MyTemp;
template <class T> std::ostream& operator<< (std::ostream&, const MyTemp<T>&);

template <class T>
class MyTemp {
public:
    friend std::ostream& operator<< <>(std::ostream& os, const MyTemp<T>& a);
    // With a template thingy here  ^^

private:
    void print(std::ostream& os, char ofc = ' ') const;
};

template <class T>
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) {
    a.print(os);
    return os;
}

或者您可以内联定义运算符:

template <class T>
class MyTemp {
public:
    friend std::ostream& operator<<(std::ostream& os, const MyTemp<T>& a) {
        a.print(os);
        return os;
    }

private:
    void print(std::ostream& os, char ofc = ' ') const;
};

关于你的上一个问题:

  

其次,一旦修复了,我只需在a.print(os)重载内调用<<吗?我知道它需要返回ostream

确实需要返回ostream - 所以只返回传入的那个,就像我的示例代码一样。

答案 1 :(得分:1)

此错误表示链接器无法识别符号。您收到此错误的变量是什么 还请检查堆栈,因为有一个std :: stack类可用。

答案 2 :(得分:0)

由于您的print会员功能是公开的,因此无需将operator<<声明为friend

请注意您使用的课​​程Stack是您的重载,以及上面的MyTemp ...