我正在用C++编写一个小矩阵库来进行矩阵运算.然而,我的编译器抱怨,在它之前没有.这个代码留在架子上6个月,在我之间我将我的计算机从debian etch升级到lenny(g ++(Debian 4.3.2-1.1)4.3.2)然而我在具有相同g ++的Ubuntu系统上遇到了同样的问题.
这是我的矩阵类的相关部分:
namespace Math { class Matrix { public: [...] friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix); } }
而"实施":
using namespace Math; std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) { [...] }
这是编译器给出的错误:
matrix.cpp:459:错误:'std :: ostream&Math :: Matrix :: operator <<(std :: ostream&,const Math :: Matrix&)'必须只取一个参数
我对这个错误感到有些困惑,但是在6个月里做了大量的Java后,我的C++又变得有点生疏了.:-)
只是告诉你另一种可能性:我喜欢使用朋友定义:
namespace Math { class Matrix { public: [...] friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix) { [...] } }; }
该函数将自动定位到周围的命名空间Math
(即使它的定义出现在该类的范围内),但除非您使用Matrix对象调用operator <<这将使参数相关的查找找到该操作符定义,否则将不可见.这有时可以帮助进行模糊调用,因为除了Matrix之外的参数类型它是不可见的.在编写其定义时,您还可以直接引用Matrix和Matrix本身定义的名称,而无需使用一些可能长的前缀限定名称并提供类似的模板参数Math::Matrix
.
你已宣布你的职能为friend
.它不是班上的成员.您应该Matrix::
从实现中删除.friend
表示指定的函数(不是该类的成员)可以访问私有成员变量.实现该函数的方式就像一个Matrix
类的实例方法,这是错误的.
要添加到Mehrdad的答案,
namespace Math { class Matrix { public: [...] } std::ostream& operator<< (std::ostream& stream, const Math::Matrix& matrix); }
在您的实施中
std::ostream& operator<<(std::ostream& stream, const Math::Matrix& matrix) { matrix.print(stream); //assuming you define print for matrix return stream; }
假设我们谈论过载operator <<
对源自所有类std::ostream
来处理Matrix
类(而不是重载<<
为Matrix
类),它更有意义的声明在标题中数学命名空间外的过载功能.
仅当通过公共接口无法实现功能时才使用友元功能.
Matrix.h
namespace Math { class Matrix { //... }; } std::ostream& operator<<(std::ostream&, const Math::Matrix&);
请注意,运算符重载是在命名空间之外声明的.
Matrix.cpp
using namespace Math; using namespace std; ostream& operator<< (ostream& os, const Matrix& obj) { os << obj.getXYZ() << obj.getABC() << '\n'; return os; }
另一方面,如果您的过载功能确实需要成为朋友,即需要访问私人和受保护的成员.
MATH.H
namespace Math { class Matrix { public: friend std::ostream& operator<<(std::ostream&, const Matrix&); }; }
您需要使用命名空间块而不是仅包含函数定义using namespace Math;
.
Matrix.cpp
using namespace Math; using namespace std; namespace Math { ostream& operator<<(ostream& os, const Matrix& obj) { os << obj.XYZ << obj.ABC << '\n'; return os; } }
在C++ 14中,您可以使用以下模板打印任何具有T :: print(std :: ostream&)const的对象; 会员.
templateauto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os) { t.print(os); return os; }