C++ 重新定义现有 class 的输出流

C++ redefine output stream of existing class

我正在使用 OpenCV,但我不喜欢以下输出:

std::cout << matrix << std::endl; 当矩阵的类型为 cv::Mat.

是否可以在不修改 class 代码的情况下重新定义运算符 << 对现有 class 对象的影响?

我知道我可以编写一个简单的函数来从 cv::Mat 中生成一个字符串,但结果可读性较差(我认为),而且我是 C++ 的初学者,所以我可能错过了东西。

我找到了 this SO question 所以我尝试了:

#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>

std::ostream& operator<<(std::ostream& os, const cv::Mat& mat)
{
     os << "test";
     return os;
}

int main(int argc, char** argv)
{
    cv::Mat m(2,2, CV_8UC3, cv::Scalar(0,0,255));
    std::cout << m << std::endl;
}

但是我得到了:

main.cpp:14:18: error: ambiguous overload for ‘operator<<’ in ‘std::cout << m’

编辑: 我不认为它是 this question 的副本,因为我无权访问库的代码(OpenCV 是开源的,所以我可以理论上修改它,但这不是一个好主意:更难维护,更难重新分发我的代码等)。

cv::Mat 已经有一个用户定义的 operator<< 重载,您不能自己添加另一个重载,您必须更改重载或添加某种函数来执行您的操作希望它这样做,只要它不是已经为 class.

定义的运算符

您不能用另一个重载替换一个重载。如果输出运算符有合适的钩子来改变输出的变化方式,则可能有机会以这种方式修改输出。我不知道这个特定的输出运算符是否有这样的钩子。

合理可读的解决方法是创建一个简单的包装器:

struct MatFormatter {
    cv::Mat const& mat;
};
std::ostream& operator<< (std::ostream& out, MatFormatter const& formatter) {
    // format formatter.mat to your liking
}
MatFormatter format(cv::Mat const& mat) {
    return MatFormatter{mat};
}
// ...
out << format(mat) << '\n';