Fra*_*ank 8 c++ outputstream ostream
我想编写一个函数来输出ostream传入的内容,并返回流,如下所示:
std::ostream& MyPrint(int val, std::ostream* out) {
*out << val;
return *out;
}
int main(int argc, char** argv){
std::cout << "Value: " << MyPrint(12, &std::cout) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印这样的值会很方便,并将函数调用嵌入到输出操作符链中,就像我一样main().
但它不起作用,打印出来:
$ ./a.out
12Value: 0x6013a8
Run Code Online (Sandbox Code Playgroud)
期望的输出是这样的:
Value: 12
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?我是否必须定义一个operator<<?
更新:澄清了所需的输出.
更新2:有些人不明白为什么我会打印这样的数字,使用函数而不是直接打印它.这是一个简化的例子,实际上该函数打印的是复杂的对象而不是int.
Ste*_*sop 11
你无法修复这个功能.规范中没有任何内容要求编译器针对同一表达式中某些不相关的运算符以任何特定顺序计算表达式中的函数调用.因此,在不更改调用代码的情况下,您无法进行MyPrint()评估std::cout << "Value: "
从左到右的顺序是由多个连续的<<运算符组成的表达式强制执行的,因此可以使用.操作符<<返回流的点是当操作符被链接时,每个操作符的LHS由操作符的左侧评估提供.
您无法通过自由函数调用实现相同的功能,因为它们没有LHS.MyPrint()返回一个等于的对象std::cout,也是如此std::cout << "Value: ",所以你正在有效地做std::cout << std::cout,这就是打印那个十六进制值.
由于所需的输出是:
Value: 12
Run Code Online (Sandbox Code Playgroud)
"正确"的事情确实要覆盖运营商<<.这通常意味着你需要让它成为朋友,或者这样做:
class WhateverItIsYouReallyWantToPrint {
public:
void print(ostream &out) const {
// do whatever
}
};
ostream &operator<<(ostream &out, const WhateverItIsYouReallyWantToPrint &obj) {
obj.print(out);
}
Run Code Online (Sandbox Code Playgroud)
如果operator<<你的类的覆盖是不合适的,例如因为你可能想要打印多种格式,并且你想为每个格式编写不同的函数,那么你应该放弃运算符链接的想法而只是调用函数,或者编写多个类,将对象作为构造函数参数,每个类都有不同的运算符重载.
你想让MyPrint成为一个有朋友运营商<<的班级:
class MyPrint
{
public:
MyPrint(int val) : val_(val) {}
friend std::ostream& operator<<(std::ostream& os, const MyPrint& mp)
{
os << mp.val_;
return os;
}
private:
int val_;
};
int main(int argc, char** argv)
{
std::cout << "Value: " << MyPrint(12) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此方法要求您将MyPrint对象插入到您选择的流中.如果您真的需要能够更改哪个流处于活动状态,则可以执行以下操作:
class MyPrint
{
public:
MyPrint(int val, std::ostream& os) : val_(val), os_(os) {}
friend std::ostream& operator<<(std::ostream& dummy, const MyPrint& mp)
{
mp.os_ << mp.val_;
return os_;
}
private:
int val_;
std::ostream& os_
};
int main(int argc, char** argv)
{
std::cout << "Value: " << MyPrint(12, std::cout) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)