C++ 为模板类重载友元运算符 <<

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1297609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:27:52  来源:igfitidea点击:

Overloading friend operator << for template class

c++operators

提问by trikker

I'm trying to overload the operator << as a friend to a template class Pair, but I keep getting a compiler warning saying

我试图重载运算符 << 作为模板类 Pair 的朋友,但我不断收到编译器警告说

friend declaration std::ostream& operator<<(ostream& out, Pair<T,U>& v) declares a non template function

for this code:

对于此代码:

friend ostream& operator<<(ostream&, Pair<T,U>&);

it gives a second warning as a recommendation saying

它给出了第二个警告作为建议说

if this is not what you intended, make sure the function template has already been declared and add <> after the function name here

Here is the function definition

这是函数定义

template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v)
{
    out << v.val1 << " " << v.val2;
}

and here is the whole class.

这是整个班级。

template <class T, class U>
class Pair{
public:
    Pair(T v1, U v2) : val1(v1), val2(v2){}
    ~Pair(){}
    Pair& operator=(const Pair&);
    friend ostream& operator<<(ostream&, Pair<T,U>&);

private:
    T val1;
    U val2;
};

I wasn't sure what to draw from the recommendation warning, other than that maybe I have to put somewhere in the friend declaration. Does anyone know the proper syntax for this? Thanks.

我不确定要从推荐警告中得出什么,除此之外,我可能必须在朋友声明中的某个地方。有谁知道正确的语法吗?谢谢。

采纳答案by Asik

You declare operator<< as returning an ostream&, but there is no return statement at all in the method. Should be:

您将 operator<< 声明为返回 ostream&,但该方法中根本没有 return 语句。应该:

template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v)
{
    return out << v.val1 << " " << v.val2;
}

Other than that, I have no problems or warnings compiling your code under Visual Studio 2008 with warnings at level 4. Oh, there are the classical linker errors, but that is easily bypassed by moving the template function definition to the class declaration, as explained in the C++ FAQ.

除此之外,我在 Visual Studio 2008 下编译您的代码没有任何问题或警告,警告级别为 4。哦,有经典的链接器错误,但是通过将模板函数定义移动到类声明,很容易绕过,如解释在C++ FAQ 中

My test code:

我的测试代码:

#include <iostream>
using namespace std;

template <class T, class U>
class Pair{ 
public:
    Pair(T v1, U v2) : val1(v1), val2(v2){}
    ~Pair(){}
    Pair& operator=(const Pair&);
    friend ostream& operator<<(ostream& out, Pair<T,U>& v)
    {
        return out << v.val1 << " " << v.val2;
    }
private:    
    T val1;
    U val2;
};

int main() {
    Pair<int, int> a(3, 4);
    cout << a;      
}

回答by Johannes Schaub - litb

You want to make one single instance (called "specialization" in generic terms) of that template a friend. You do it the following way

您希望将该模板的一个实例(在通用术语中称为“专业化”)成为朋友。你按以下方式做

template <class T, class U>
class Pair{
public:
    Pair(T v1, U v2) : val1(v1), val2(v2){}
    ~Pair(){}
    Pair& operator=(const Pair&);
    friend ostream& operator<< <> (ostream&, Pair<T,U>&);

private:
    T val1;
    U val2;
};

Because the compiler knows from the parameter list that the template arguments are Tand U, you don't have to put those between <...>, so they can be left empty. Note that you have to put a declaration of operator<<above the Pairtemplate, like the following:

因为编译器从参数列表中知道模板参数是Tand U,所以您不必将<...>它们放在 之间,因此它们可以留空。请注意,您必须operator<<Pair模板上方放置一个声明,如下所示:

template <class T, class U> class Pair;

template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v);

// now the Pair template definition...

回答by wkliang

Simple inline version:

简单的内联版本:

template<typename T> class HasFriend {
    private:
        T item;
    public:
       ~HasFriend() {}
       HasFriend(const T &i) : item(i) {}
    friend ostream& operator<<(ostream& os, const HasFriend<T>& x) {
        return os << "s(" << sizeof(x) << ").op<<" << x.item << endl;
    }
};

Revised template version:

修改后的模板版本:

template<template<typename /**/> class U, typename V>
ostream& operator<<(ostream &os, const U<V> &x) {
    return os << "s(" << sizeof(x) << ").op<<" << x.item << endl;
}

template<typename T> class HasFriend {
    private:
        T item;
    public:
       ~HasFriend() {}
       HasFriend(const T &i) : item(i) {}
    friend ostream& operator<<<>(ostream&, const HasFriend<T>&);
};