我正在用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++已经有点生疏了。: -)
在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;
}
在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;
}
只是告诉你另一种可能性:我喜欢使用朋友的定义:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix) {
[...]
}
};
}
The function will be automatically targeted into the surrounding namespace Math (even though its definition appears within the scope of that class) but will not be visible unless you call operator<< with a Matrix object which will make argument dependent lookup find that operator definition. That can sometimes help with ambiguous calls, since it's invisible for argument types other than Matrix. When writing its definition, you can also refer directly to names defined in Matrix and to Matrix itself, without qualifying the name with some possibly long prefix and providing template parameters like Math::Matrix<TypeA, N>.