尝试重载时出错<<操作员和使用朋友功能

时间:2015-01-11 04:27:36

标签: c++

我正在尝试重载<< 运算符并使用友元函数。 下面的代码块工作正常。

template <class T>
class Mystack{
    friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d)
    {
        d.print(s);
        return s;
    } 
};

由于它是友元函数,我显然希望在不使用范围解析运算符的情况下在类外定义它。但是,当我尝试时,我会收到错误。

template <class T>
class Mystack{
    friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d); 
};
template <class T>
std::ostream& operator<<(std::ostream& s, Mystack<T> const& d)
{
    d.print(s);
    return s;
}

以下是主要

的代码段
Mystack<int> intstack;
std::cout << intstack;

错误:未解析的extrernal符号。

P.S:它不是完整的运行代码。只是一个样本。请耐心等待。

1 个答案:

答案 0 :(得分:4)

friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d);

声明并成为非模板operator<<函数的朋友。因此Mystack<int>将其朋友作为非模板函数std::ostream& operator<<(std::ostream& s, Mystack<int> const& d);等等。

template<class T>
std::ostream& operator<<(std::ostream& s, Mystack<T> const& d)
{
    d.print(s);
    return s;
}

定义了operator<<函数模板。

两者不一样。当您编写std::cout << intstack;时,重载决策规则将其解析为您声明的非模板operator<<函数,但它没有定义,因此您会收到链接器错误。

无法为类模板外的类模板的每个实例化定义非模板函数。但是,您可以与operator<<功能模板的专业化建立友好关系:

// forward declarations
template <class T>
class Mystack;
template <class T>
std::ostream& operator<<(std::ostream& s, Mystack<T> const& d);

template <class T>
class Mystack
{
    friend std::ostream& operator<< <T>(std::ostream& s, Mystack<T> const& d); 
//                                  ^^^
};

或与函数模板的每个特化相关,从封装的角度来看这更糟糕(因为,例如,operator<< <int>将是Mystack<float>的朋友):

template <class T>
class Mystack
{
public:
    template <class U>
    friend std::ostream& operator<<(std::ostream& s, Mystack<U> const& d);
};

或者只是在类中定义友元函数。