尝试重载运算符并使用友元函数时出错<<



我正在尝试重载运算符并使用朋友函数<<</strong>。下面的代码块工作得很好。

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

下面是 main 的代码片段

Mystack<int> intstack;
std::cout << intstack;

错误:未解析的极值符号。

PS:它不是完整的运行代码。只是一个示例。请熊。

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

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

相关内容

最新更新