Zac*_*ing 5 c++ const reference temporary object
我有一种特殊的ostringstream,试图将文本输出为临时对象,但遇到了一些麻烦。要明确的是,这本质上是我想要做的:
ostringstream() << "PARTY DOWN!" << endl;
Run Code Online (Sandbox Code Playgroud)
现在,您要说:“但是Zack,该代码完全不值钱!该对象在行尾被销毁,您什至不知道它是否做了什么?”,听听我的声音。我不尝试使用普通的ostringstreams来执行此操作,而是尝试使用派生类,在该派生类中,析构函数实际上为数据提供了退出对象的路径。所以实际上,它看起来更像是这样:
specialstringstream() << "PARTY DOWN!" << endl;
Run Code Online (Sandbox Code Playgroud)
其中specialstringstream具有析构函数,该析构函数将文本转储到其他位置。
关于执行此操作的原因,我不会赘述。您必须相信我,这对我需要做的事情很有意义,并且非常适合现有的巨大代码库。
这里的问题是:执行此操作时,所有内容都可以编译并运行,但是我得到了指向输出的指针地址,而不是“ PARTY DOWN!”。串。我确定发生了这种情况,因为编译器选择的用于执行流输出的运算符
ostream& operator<< (const void* val)不是ostream& operator<< (ostream& out, const char* s )。
我对为什么有一个模糊的想法,但是我对如何解决它一无所知。如何使char * s打印到字符串流的临时实例中?
这是SpecialStringStream对象的简短版本,它表现出以下行为:
class SpecialStringStream : public ostringstream
{
public:
SpecialStringStream(ostream* regularStream)
{
regularStream_ = regularStream;
}
~SpecialStringStream()
{
if (regularStream_ != NULL)
(*regularStream_) << str();
}
private:
ostream* regularStream_;
};
Run Code Online (Sandbox Code Playgroud)
当我执行以下操作时:SpecialStringStream(someStreamPtr) << "PARTY DOWN!" << endl;,我在输出而不是消息中得到了一个类似于“ 00444D60”的指针地址。
编辑:由于我不是一个新用户,无法回答我自己的问题,因此感谢所有答复,这里就是我所决定的。
我想出了以下解决方案,该解决方案可在Visual C ++ 8和我需要的所有其他编译器下使用。我创建了一个模板运算符,该运算符基本上会删除其const常量的const SpecialStringStream,将其强制转换为ostream,然后让ostream运算符执行其操作。随时将其撕成碎片,并向我警告我介绍的所有潜在潜在错误!
template <class T>
std::ostream& operator<<(const SpecialStringStream &o, T msg)
{
return static_cast<std::ostream&>(const_cast<SpecialStringStream&>(o)) << msg;
}
Run Code Online (Sandbox Code Playgroud)
重载ostream& operator<< (ostream& out, const char*)是不可行的,因为您的临时对象不会绑定到非常量引用ostream&。除了声明局部变量并使用它之外,您实际上无能为力(因为您无法将右值转换为左值):
{
specialstringstream ss;
ss << "Hello world" << std::endl; // OK, can bind to lvalue
}
Run Code Online (Sandbox Code Playgroud)
可能的解决方案:您可以声明另一个接受右值引用的重载:
std::ostream & operator<<(specialstringstream && o, const char * s)
{
return o << s; // note: *not* "std::move(o)"
}
Run Code Online (Sandbox Code Playgroud)