简体   繁体   English

问题与std :: ostringstream

[英]Problem with std::ostringstream

I tried to make the code #1 more terse by changing it to code #2 but it doesn't work as expected. 我试图通过将代码1更改为代码2使代码1更加简洁,但它没有按预期工作。 Can anyone please tell me why it doesn't work? 谁能告诉我为什么它不起作用? Thanks. 谢谢。

Code #1 代码#1

double x = 8.9, y = 3.4, z = -4.5;
std::ostringstream q0;
q0 << "(" << x << "," << y << "," << z << ")";
std::string s = q0.str();


Code #2 代码#2

double x = 8.9, y = 3.4, z = -4.5;
std::string s = static_cast<std::ostringstream &>(
  std::ostringstream() << "(" << x << "," << y << "," << z << ")").str();


I've reproduced your garbage. 我转载了你的垃圾。 The only thing I can think of is that your static cast is invalid. 我唯一能想到的是您的静态转换无效。 That seems really odd to me but it's the only thing I can think might be happening. 这对我来说确实很奇怪,但这是我唯一可能想到的事情。 It could be that op<< returns something other than ostringstream that is not castable to ostringstream...like a reference stream of some sort. 可能op <<返回了ostringstream之外的其他内容,这些内容无法转换为ostringstream……类似于某种引用流。 In fact, when assigning the reference to a variable and looking at the type in a debugger, it looks weird for a ostringstream. 实际上,当将引用分配给变量并在调试器中查看类型时,对于ostringstream来说看起来很奇怪。

At any rate, there's no reason to be "terse". 无论如何,没有理由变得“简洁”。 In fact, being terse is often quite annoying to other developers who have to read your code. 实际上,过于简洁通常会使其他不得不阅读您的代码的开发人员感到烦恼。 If you want to be "terse", put you stream stuff in a function that returns a string and name it something useful. 如果您想变得“简洁”,请将您的内容放入返回字符串的函数中并命名为有用的函数。

Edit: 编辑:

Actually, I think I may have a better answer. 实际上,我认为我可能有一个更好的答案。 You're binding a non-const reference to a temporary and calling a function on it. 您正在将非常量引用绑定到临时并在其上调用函数。 A const reference is guaranteed to continue existing until the end of the 'statement' (forgetting the technical term right now but it's close). 保证const引用将继续存在,直到“语句”结束为止(立即忘记技术术语,但已结束)。 A non-const reference does not have this guarantee. 非常量引用不具有此保证。 Therefore I think you are eliciting undefined behavior when you call str() on this non-const reference because the compiler is free to delete the temporary it refers to. 因此,我认为当您在此非const引用上调用str()时,会引起未定义的行为,因为编译器可以自由删除其引用的临时项。

您可能需要使用此答案中提供的代码。

I asked a similar question a while ago. 我前段时间也问过类似的问题 The answers explain why what you've done doesn't work (you might have encountered either compile-time errors or printing strings as hex addresses like I did), and how to get around it (Johannes Schaub posted a very nice workaround using getlval() ). 答案解释了为什么您的工作不起作用(您可能遇到编译时错误或像我一样用十六进制地址打印字符串)以及解决方法(Johannes Schaub发表了使用getlval()的非常好的解决方法getlval() )。

如果您可以访问boost格式库 ,则以下内容可能会更“简洁”。

cout << boost::format("writing %1%,  x=%2% : %3%-th try") % "toto" % 40.23 % 50;

You have the answer as to "why" above which has been addressed. 您已经对上面提到的“为什么”有了答案。

A quick suggestion is that you can always make your thing work by substituting ostringstream() with ostringstream().flush() . 一个快速的建议是,您总是可以用ostringstream().flush()代替ostringstream()来使您的事情正常工作。 That makes the result eligible for ref-to-non-const binding. 这使得结果符合引用到非const绑定的条件。

Some of the ostream operator<< overloads — in particular those for std::string and char const* are free functions, like: ostream operator<<重载,尤其是std::stringchar const*重载是自由函数,例如:

ostream& operator<<(ostream& os, T const&);

If the stream is a temporary (which in your case it is), it cannot bind to that ref-to-non-const , and the overload cannot be chosen. 如果流是临时的(在您的情况下为临时流),则它无法绑定到该ref-to-non-const ,并且无法选择重载。

So you are instead accidentally using a non-preferred overload by accident; 因此,您意外地偶然使用了非首选的重载; in this case, the overload for void const* . 在这种情况下, void const*的重载。 That's why you're seeing pointer contents (it's not "garbage"). 这就是为什么您看到指针内容(不是“垃圾”)的原因。

This is a limitation when trying to do this serialisation on a single line, and you can't get around it. 当尝试在单行上执行此序列化时,这是一个限制,您将无法解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM