如何在模板类中重载插入(<<)和/或extract(>>)运算符而不使其内联。我想要<<或>>运营商作为朋友类。 我知道如何使它内联 矩阵类中的内联示例
friend ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
...
// create the ostr
return ostr;
}
但我希望代码在templateclass定义之外。
g ++告诉我添加&lt;&gt;在函数名之后,我做了但当我尝试实例化SOMETYPE类型的矩阵时,它给了我一个错误,它不知道如何提取或插入该类型。
答案 0 :(得分:2)
尝试类似:
template <typename T> class Matrix;
template <typename T> std::ostream& operator<<(std::ostream& ostr, const Matrix<T>& m);
template <Typename T>
class Matrix
{
public:
friend ostream& operator<< <T> (ostream& ostr, const Matrix<K>& inputMatrix);
};
// This must be in the same translation unit as the class definition!
template<typename T>
ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
// ...
return ostr;
}
重新编辑以解决aschepler和dribeas的评论。
答案 1 :(得分:1)
将代码放在类定义之外的标题中。或者,将其放在.tcc
文件中,并将其包含在标题的底部。
答案 2 :(得分:1)
如果你真的想在外部定义运算符并且只与这个模板实例化的类型一致的运算符实例化,那么正确的语法是:
template <typename T> class test; // forward declare template class
template <typename T> // forward declare the templated operator
std::ostream& operator<<( std::ostream&, test<T> const & );
template <typename T>
class test { // define the template
friend std::ostream& operator<< <T>( std::ostream&, test<T> const & ); // befriend
};
template <typename T> // define the operator
std::ostream& operator<<( std::ostream& o, test<T> const & ) {
return o;
}
在大多数情况下,将定义排除在课堂之外是不值得的,因为您仍然需要在标题中提供它并需要额外的工作。
另请注意,编译器在查找方面存在细微差别。在函数内联类定义的情况下,编译器将找不到该函数,除非其中一个参数实际上是模板的类型,因此它有效地降低了可见性和数量编译器必须完成的工作(如果模板化的operator<<
是在类之外定义的,编译器会在找到a << b
的所有地方找到它作为重载解析的候选者,只丢弃它在第二个参数不是test<T>
的所有情况下(并且它会将模板化运算符显示为所有错误消息中的候选者,它不能与operator<<
匹配,这已经是一个足够长的列表)。