C++ 模板类和插入提取重载

C++ 模板类和插入提取重载,c++,templates,operator-overloading,inline,insertion,C++,Templates,Operator Overloading,Inline,Insertion,如何使insertion()运算符在模板类中重载,而不使其内联。我希望将>操作符作为朋友类。 我知道如何使它内联 矩阵类中的内联示例 friend ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix) { ... // create the ostr return ostr; } friend-ostream&operator将代码放在类定义之外的头中。

如何使insertion()运算符在模板类中重载,而不使其内联。我希望将>操作符作为朋友类。 我知道如何使它内联 矩阵类中的内联示例

friend ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
   ...
   // create the ostr
   return ostr;
}

friend-ostream&operator将代码放在类定义之外的头中。或者,将其放在
.tcc
文件中,并将其包含在标题底部。

尝试以下操作:

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;
}
模板类矩阵;

template std::ostream&operator如果您确实希望在外部定义运算符,并且只与类型与此模板实例化一致的运算符实例化交朋友,则正确的语法为:

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;
}
模板类测试;//前向声明模板类
模板//正向声明模板化运算符

std::ostream&operator您应该阅读。顺便说一句,作为模板函数,它将隐式内联。下次,请使用编辑窗格顶部的
101010
按钮格式化消息中的代码。编辑窗格右侧的“如何编辑”浮动窗口对此进行了解释。我认为您需要在函数定义中使用
const Matrix&
。(声明可以使用注入的类名
Matrix
来表示
Matrix
,但这在定义中不可见。)@aschepler,应该纠正这个问题。第二件事你也是对的——在课堂上,我可以说
Matrix
,而不是
Matrix
。奇怪的是在操作符的类声明中必须使用不同的标识符,而不是
T
。也许这是我使用的GCC版本的一个怪癖,或者可能是一个VisualStudio扩展,允许您这样做。有人知道标准是怎么说的吗?您的版本授予所有
操作符友谊。re:the standard:14.5.3p1:“类或类模板的朋友可以是函数模板或类模板,函数模板或类模板的特殊化,或普通(非模板)函数或类。”带有另一个
类K
参数的版本将整个函数模板声明为好友。我的pastebin链接中的版本将函数模板的一个特殊化声明为friend。我本来打算在这里写一条评论,但觉得太长了。我的回答中提供了将模板的单个实例化声明为友元的正确代码。您能举例说明为什么必须预先声明模板运算符吗?@Silverrocker:主要原因是该语言的设计考虑了单遍编译器(*)。问题是
friend
语句告诉编译器:授予对模板的这个特定实例化的访问权。为了使编译器有意义,模板必须已经声明。它类似于:
voidfoo(){bar(5);}模板voidbar(T){}
。在声明泛型模板和专门化之前,不能使用或引用类模板的专门化或实例化。(*)这是一个目标,而不是现实,因为其他原因,所有编译器都需要多次检查输入文件。我在某个地方读到,对初始代码执行较少传递的代码有3次传递——包括预处理器。我无法提供该语句源代码的链接,也不记得它是什么编译器。