棘手的基于串流的临时 [英] tricky stringstream-based temporary

查看:57
本文介绍了棘手的基于串流的临时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨大家好,

我写一个类,从stringstream中删除,收集

项目,一旦完成就会将它们写入std :: cout一气呵成。除非我将它作为临时用途,否则它的工作原理很好。这是一个很小的测试程序:


#include< iostream>

#include< sstream>


class Gatherer:public std :: stringstream {

public:


~Gatherer(void){

std :: cout << this-> str()<< std :: endl;

}


};


int main(void){

{

Gatherer()<< hello world!;

}

{

Gatherer聚集;

聚集<< 你好世界!;

}

{

Gatherer()<< std :: dec<< hello world!;

}

}

在我的机器上打印:


0x8049e48

你好世界!

你好世界!


所以,显然第一行是一个地址。我对此没有任何解释。我特别感到困惑的是第三行。
。插入一个std :: dec不应该

有这个效果,还是应该呢?

最好的问候


Kai-Uwe

解决方案

" Kai-Uwe Bux" < JK ******** @ gmx.net>写了...

我在编写一个类,从stringstream中删除,收集
项目,一旦完成它将一次性写入std :: cout。它的工作原理很好,除非我把它当作临时用的。这是一个很小的测试程序:

#include< iostream>
#include< sstream>

类Gatherer:public std :: stringstream {
public:

〜收集者(无效){
std :: cout<< this-> str()<< std :: endl;
}

};

int main(void){
{
Gatherer()<< 你好世界!;
}
{GAPherer聚集;
收集<< 你好世界!;
}
{/ / Gatherer()<< std :: dec<< 你好世界!;
}
}

在我的机器上,它打印出来:

0x8049e48
hello world!<你好世界!

所以,显然第一行是一个地址。我对此没有任何解释。
我对第三行感到特别困惑。插入一个std :: dec不应该有这种效果,还是应该呢?




我认为你遇到了同步问题。当使用Intel v4.5或VC ++ v6sp5编译

时,此代码输出三个hello。当使用VC ++ v7.1编译

时,它首先打印一个地址,然后打印两个

你好,就像你描述的那样。


我认为你得到的是,当析构函数执行时,

所有的赌注都是关闭的 - 这个 - >> str()的内容,它可能不包含

任何东西,或者返回一个有效的物品......你可能会招致UB。

只是一个猜测。


Victor


Victor Bazarov写道:

" Kai-Uwe Bux" < JK ******** @ gmx.net>写了...

我在编写一个类,从stringstream中删除,收集
项目,一旦完成它将一次性写入std :: cout。它的工作原理很好,除非我把它当作临时用的。这是一个很小的测试程序:

#include< iostream>
#include< sstream>

类Gatherer:public std :: stringstream {
public:

〜收集者(无效){
std :: cout<< this-> str()<< std :: endl;
}

};

int main(void){
{
Gatherer()<< 你好世界!;
}
{GAPherer聚集;
收集<< 你好世界!;
}
{/ / Gatherer()<< std :: dec<< 你好世界!;
}
}

在我的机器上,它打印出来:

0x8049e48
hello world!<你好世界!

所以,显然第一行是一个地址。我对此没有任何解释。


特别困惑于第三行。插入一个std :: dec应该不会产生这种影响,还是应该呢?



我认为你遇到了同步问题。使用Intel v4.5或VC ++ v6sp5编译时,此代码输出三个hello。当用VC ++ v7.1编译时,它首先打印一个地址,然后打印两个
你好,就像你描述的那样。

我认为你得到的是当时的析构函数正在执行,
所有的赌注都是关闭这个 - > str()的内容,它可能不包含
任何东西,或者返回一个有效的对象......你可能会招致UB。只是一个猜测。

Victor




感谢您的帮助。


我取消继承作为问题的可能来源:


#include< fstream>


int main(无效){

std :: ofstream(" greeting.out")<< hello world!\ n;

}

编译好。但它确实出现了意想不到的事情(好吧,截至目前,我实际上是在期待这一点):


news_group> cat greeting.out

0x8048a01news_group>

所以问题肯定在于临时创建。

标准是否说临时流有未定义的行为?我认为
的印象是,临时应该像真实的东西一样

,除了它的生命周期只有极少数

保证(就像它至少可以看到

表达式的完成一样)。


截至目前,我我正在考虑它可能是我的

标准库中的错误。

再次感谢


Kai-Uwe


Kai-Uwe Bux写道:


int main(void){
{
Gatherer()<< 你好世界!;
}
{GAPherer聚集;
收集<< 你好世界!;
}
{/ / Gatherer()<< std :: dec<< hello world!;
}
}




你不应该为非const引用传递临时值

参数(在这种情况下,运算符的第一个参数<<)。结果

这样做是未定义的。


-

Russell Hanneken
eu ******* @ cbobk.pbz

使用ROT13解码我的电子邮件地址。


Hi folks,
I have trouble writing a class, derving from stringstream, that collects
item and once it''s done will write them to std::cout in one go. It works
fine except when I use it as a temporary. Here is a tiny test programm:

#include <iostream>
#include <sstream>

class Gatherer : public std::stringstream {
public:

~Gatherer ( void ) {
std::cout << this->str() << std::endl;
}

};

int main ( void ) {
{
Gatherer() << "hello world!";
}
{
Gatherer gather;
gather << "hello world!";
}
{
Gatherer() << std::dec << "hello world!";
}
}
On my machine, it prints:

0x8049e48
hello world!
hello world!

So, clearly the first line is an address. I have no explanation for this. I
am especially puzzled by the third line. Inserting a std::dec should not
have this effect, or should it?
Best regards

Kai-Uwe

解决方案

"Kai-Uwe Bux" <jk********@gmx.net> wrote...

I have trouble writing a class, derving from stringstream, that collects
item and once it''s done will write them to std::cout in one go. It works
fine except when I use it as a temporary. Here is a tiny test programm:

#include <iostream>
#include <sstream>

class Gatherer : public std::stringstream {
public:

~Gatherer ( void ) {
std::cout << this->str() << std::endl;
}

};

int main ( void ) {
{
Gatherer() << "hello world!";
}
{
Gatherer gather;
gather << "hello world!";
}
{
Gatherer() << std::dec << "hello world!";
}
}
On my machine, it prints:

0x8049e48
hello world!
hello world!

So, clearly the first line is an address. I have no explanation for this. I am especially puzzled by the third line. Inserting a std::dec should not
have this effect, or should it?



I think you''re running into synchronisation problem. When compiled
with Intel v4.5 or VC++ v6sp5, this code outputs three hello. When
compiled with VC++ v7.1, it prints an address first and then two
hello, just like you described.

I think what you get is that by the time the destructor is executing,
all bets are off WRT the contents of this->str(), it may not contain
anything, or return a valid object... You might be incurring the UB.
Just a guess.

Victor


Victor Bazarov wrote:

"Kai-Uwe Bux" <jk********@gmx.net> wrote...

I have trouble writing a class, derving from stringstream, that collects
item and once it''s done will write them to std::cout in one go. It works
fine except when I use it as a temporary. Here is a tiny test programm:

#include <iostream>
#include <sstream>

class Gatherer : public std::stringstream {
public:

~Gatherer ( void ) {
std::cout << this->str() << std::endl;
}

};

int main ( void ) {
{
Gatherer() << "hello world!";
}
{
Gatherer gather;
gather << "hello world!";
}
{
Gatherer() << std::dec << "hello world!";
}
}
On my machine, it prints:

0x8049e48
hello world!
hello world!

So, clearly the first line is an address. I have no explanation for this.


I

am especially puzzled by the third line. Inserting a std::dec should not
have this effect, or should it?



I think you''re running into synchronisation problem. When compiled
with Intel v4.5 or VC++ v6sp5, this code outputs three hello. When
compiled with VC++ v7.1, it prints an address first and then two
hello, just like you described.

I think what you get is that by the time the destructor is executing,
all bets are off WRT the contents of this->str(), it may not contain
anything, or return a valid object... You might be incurring the UB.
Just a guess.

Victor



Thanks for your help.

I eliminated inheritance as a possible source of the problem:

#include <fstream>

int main ( void ) {
std::ofstream( "greeting.out" ) << "hello world!\n";
}
This compiles fine. But it does unexpected things (well, as of now, I
actually was expecting this):

news_group> cat greeting.out
0x8048a01news_group>
So the problem definitely lies in the fact that a temporary is created.
Does the standard say that temporary streams have undefined behaviour? I
was under the impression that a temporary is supposed to behave exactly
like the real thing except that for its life time there are only very few
guarantees (like it will live at least to see the completion of the
expression of which it is a part).

As of now, I am considering the possibility that it could be a bug in my
standard library.
Thanks again

Kai-Uwe


Kai-Uwe Bux wrote:


int main ( void ) {
{
Gatherer() << "hello world!";
}
{
Gatherer gather;
gather << "hello world!";
}
{
Gatherer() << std::dec << "hello world!";
}
}



You''re not supposed to pass a temporary for a non-const reference
parameter (in this case, the first parameter of operator<<). The result
of doing so is undefined.

--
Russell Hanneken
eu*******@cbobk.pbz
Use ROT13 to decode my email address.


这篇关于棘手的基于串流的临时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆