我正在尝试重载运算符<<作为模板类Pair的朋友,但我不断收到编译器警告说
friend declaration std::ostream& operator<<(ostream& out, Pair<T,U>& v) declares a non template function
代码:
friend ostream& operator<<(ostream&, Pair<T,U>&);
它给出了第二个警告,作为推荐说
if this is not what you intended, make sure the function template has already been declared and add <> after the function name here
这是功能定义
template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v)
{
out << v.val1 << " " << v.val2;
}
这是整个班级。
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;
};
我不确定从推荐警告中得到什么,除此之外我可能必须在朋友声明中放置一些内容。有谁知道这个的正确语法?感谢。
答案 0 :(得分:46)
您希望将该模板的一个实例(在通用术语中称为“专业化”)作为朋友。你可以通过以下方式实现
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;
};
因为编译器从参数列表中知道模板参数是T
和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...
答案 1 :(得分:20)
你宣布运营商&lt;&lt;作为返回ostream&amp;,但该方法中根本没有return语句。应该是:
template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v)
{
return out << v.val1 << " " << v.val2;
}
除此之外,我没有任何问题或警告在Visual Studio 2008下编译你的代码,并在第4级发出警告。哦,有传统的链接器错误,但是通过将模板函数定义移动到类声明可以很容易地绕过它,如C++ FAQ中所述。
我的测试代码:
#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;
}
答案 2 :(得分:1)
简单的内联版本:
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;
}
};
修订模板版本:
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>&);
};