我正在阅读litb对问题here的回答,在那里他详细介绍了如何创建类模板的专业友情功能。
我试图创建一个样本,它完全符合他的建议(最后代码):
// use '<>' to specialize the function template with the class template's type
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f)
导致编译器错误:
error: defining explicit specialization ‘operator<< <>’ in friend declaration
在专业化中明确声明模板参数也不起作用:
friend std::ostream& operator<< <T>(std::ostream& os, const foo<T>& f) // same error
另一方面,从使用专业化改为使用朋友功能模板代替 工作:
template<typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
所以我的问题是:
ostream operator
?以下示例代码:
#include <iostream>
// fwd declarations
template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);
template<typename T>
struct foo
{
foo(T val)
: _val(val)
{}
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f) // error line
//template<typename U>
//friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
{
return os << "val=" << f._val;
}
T _val;
};
int main()
{
foo<std::string> f("hello world");
std::cout << f << std::endl;
exit(0);
}
答案 0 :(得分:3)
在litb的例子中,他只是宣称专业化是班上的朋友。他不是定义专业化,这是你的代码所做的。您不能在类声明(或任何非命名空间范围)中定义特殊化。
您需要的是:
template <class T>
class foo;
template<class T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
return os << "val=" << f._val;
}
template<typename T>
struct foo
{
// ...
private:
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
T _val;
};
答案 1 :(得分:2)
您有两个选择:
删除fwd声明并定义课程中的所有内容。
示例强>
template <typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
{
return os << "val=" << f._val;
}
在班级之外定义朋友职能。
示例强>
template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);
template<typename T>
struct foo
{
foo(T val)
: _val(val)
{}
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
T _val;
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
return os << "val=" << f._val;
}