C ++重新定义了现有类的输出流(C++ redefine output stream of existing class)

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

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

是否有可能重新定义operator <<对现有类的对象的影响而无需修改类的代码?

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

我找到了这个问题,所以我尝试了:

#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:错误:'std :: cout << m'中'operator <<'的模糊重载

编辑:我不认为它是这个问题的重复,因为我无法访问库的代码(OpenCV是开源的,所以我理论上可以修改它,但这将是一个坏主意:更难维护,重新分配我的代码等)。

I am using OpenCV and I do not like the ouput of:

std::cout << matrix << std::endl; when matrix has type cv::Mat.

Is it possible to redefine the effect of operator << on objects of an existing class without having to modify the code of the class ?

I know that I could write a simple function that would produce a string out of a cv::Mat but the result would be less readable (I think) and I am a beginner in C++ so I may have missed something.

I found this SO question so I tried:

#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; }

But I got:

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

edit: I do not think it is a duplicate of this question because I do not have access to the code of the library (OpenCV is opensource so I could in theory modify it but that would be a bad idea: harder to maintain, to redistribute my code, etc.).

最满意答案

你不能用另一个替换过载。 如果输出操作符具有合适的挂钩来改变输出的更改方式,则可能有可能以这种方式修改输出。 这个特定的输出操作符是否有这样的钩子我不知道。

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

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';

You cannot replace an overload by another one. If the output operator has suitable hooks to change how the output is change there may be a chance to modify the output this way. Whether this particular output operator has such a hook I don't know.

The reasonably readable work-around is to create a simple wrapper:

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';C ++重新定义了现有类的输出流(C++ redefine output stream of existing class)

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

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

是否有可能重新定义operator <<对现有类的对象的影响而无需修改类的代码?

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

我找到了这个问题,所以我尝试了:

#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:错误:'std :: cout << m'中'operator <<'的模糊重载

编辑:我不认为它是这个问题的重复,因为我无法访问库的代码(OpenCV是开源的,所以我理论上可以修改它,但这将是一个坏主意:更难维护,重新分配我的代码等)。

I am using OpenCV and I do not like the ouput of:

std::cout << matrix << std::endl; when matrix has type cv::Mat.

Is it possible to redefine the effect of operator << on objects of an existing class without having to modify the code of the class ?

I know that I could write a simple function that would produce a string out of a cv::Mat but the result would be less readable (I think) and I am a beginner in C++ so I may have missed something.

I found this SO question so I tried:

#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; }

But I got:

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

edit: I do not think it is a duplicate of this question because I do not have access to the code of the library (OpenCV is opensource so I could in theory modify it but that would be a bad idea: harder to maintain, to redistribute my code, etc.).

最满意答案

你不能用另一个替换过载。 如果输出操作符具有合适的挂钩来改变输出的更改方式,则可能有可能以这种方式修改输出。 这个特定的输出操作符是否有这样的钩子我不知道。

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

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';

You cannot replace an overload by another one. If the output operator has suitable hooks to change how the output is change there may be a chance to modify the output this way. Whether this particular output operator has such a hook I don't know.

The reasonably readable work-around is to create a simple wrapper:

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';