我正在用c++编写一个用于矩阵运算的小型矩阵库。然而,我的编译器抱怨,以前它没有。这段代码被搁置了6个月,在此期间,我把我的电脑从debian etch升级到lenny (g++ (debian 4.3.2-1.1) 4.3.2
),但是我在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&
数学:矩阵::操作符< < (std::上ostream,
const Math::Matrix&)'必须取
只有一个参数
我对这个错误有点困惑,但在这6个月做了很多Java之后,我的c++已经有点生疏了。: -)
我想用一个重载<<来打印数组的例子来简化一下。
首先将两个对象类型传递给<<操作符
创建一个函数来重载操作符,如下所示。
#include<iostream>
using namespace std;
void operator<<(ostream& os, int arr[]) {
for (int i = 0;i < 10;i++) {
os << arr[i] << " ";
}
os << endl;
}
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
cout << arr;
}
如果还需要级联操作符,请确保返回cout对象
在重载函数中,
#include<iostream>
using namespace std;
ostream& operator<<(ostream& os, int arr[]) {
for (int i = 0;i < 10;i++) {
cout << arr[i] << " ";
}
cout << endl;
return os;
}
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 11,22,33,44,55,66,77,88,99,100 };
// cascading of operators
cout << arr << arr2;
}
假设我们讨论的是对std::ostream派生的所有类重载操作符<<来处理Matrix类(而不是对Matrix类重载<<),那么在头文件的Math命名空间之外声明重载函数更有意义。
只有在无法通过公共接口实现该功能时,才使用好友函数。
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&);
};
}
您需要将函数定义包含在一个名称空间块中,而不是仅仅使用名称空间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;成员。
template<class T>
auto operator<<(std::ostream& os, T const & t) -> decltype(t.print(os), os)
{
t.print(os);
return os;
}
在c++ 20中可以使用概念。
template<typename T>
concept Printable = requires(std::ostream& os, T const & t) {
{ t.print(os) };
};
template<Printable T>
std::ostream& operator<<(std::ostream& os, const T& t) {
t.print(os);
return os;
}
我想用一个重载<<来打印数组的例子来简化一下。
首先将两个对象类型传递给<<操作符
创建一个函数来重载操作符,如下所示。
#include<iostream>
using namespace std;
void operator<<(ostream& os, int arr[]) {
for (int i = 0;i < 10;i++) {
os << arr[i] << " ";
}
os << endl;
}
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
cout << arr;
}
如果还需要级联操作符,请确保返回cout对象
在重载函数中,
#include<iostream>
using namespace std;
ostream& operator<<(ostream& os, int arr[]) {
for (int i = 0;i < 10;i++) {
cout << arr[i] << " ";
}
cout << endl;
return os;
}
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 11,22,33,44,55,66,77,88,99,100 };
// cascading of operators
cout << arr << arr2;
}