我有一种特殊类型的 ostringstream,我试图将文本作为临时对象输出到其中,但我遇到了一些麻烦。需要明确的是,这基本上就是我想要做的:
ostringstream() << "PARTY DOWN!" << endl;
现在,在你说:“但是 Zack,那段代码完全没有值(value)!对象在行尾被销毁了,你怎么知道它是否做了什么?”,听我说完。我不尝试使用普通的 ostringstreams 来执行此操作,而是使用派生类,其中的析构函数实际上为数据提供了退出对象的路径。所以实际上,它看起来更像这样:
specialstringstream() << "PARTY DOWN!" << endl;
其中 specialstringstream 具有将文本转储到其他地方的析构函数。
我不会详细说明我为什么这样做。您必须相信我,它对我需要做的事情很有意义,并且非常适合现有的庞大代码库。
问题是:当我这样做时,一切都编译并运行,但我得到一个指针地址打印到我的输出而不是“PARTY DOWN!”字符串。我确定这是因为编译器选择执行流输出的运算符是
ostream& operator<< (const void* val)
, 不是 ostream& operator<< (ostream& out, const char* s )
.
我对原因有一个模糊的想法,但我不知道如何解决它。我该怎么做才能让 char*s 打印到 stringstream 的临时实例中?
这是展示行为的 SpecialStringStream 对象的简短版本:
class SpecialStringStream : public ostringstream
{
public:
SpecialStringStream(ostream* regularStream)
{
regularStream_ = regularStream;
}
~SpecialStringStream()
{
if (regularStream_ != NULL)
(*regularStream_) << str();
}
private:
ostream* regularStream_;
};
当我做类似的事情时:SpecialStringStream(someStreamPtr) << "PARTY DOWN!" << endl;
,我在输出中得到一个指针地址,如“00444D60”,而不是消息。
编辑:由于我是一个新用户,无法回答我自己的问题,因此感谢所有回复,我已经确定了这一点。
我提出了以下解决方案,它可以在 Visual C++ 8 和我需要的所有其他编译器下运行。我创建了一个模板运算符,它基本上剥离了 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;
}
最佳答案
过载 ostream& operator<< (ostream& out, const char*)
不可行,因为您的临时文件不会绑定(bind)到非常量引用 ostream&
.除了声明一个局部变量并使用它之外,您实际上无能为力(因为您不能将右值转换为左值):
{
specialstringstream ss;
ss << "Hello world" << std::endl; // OK, can bind to lvalue
}
可能的解决方案:您可以声明另一个接受右值引用的重载:
std::ostream & operator<<(specialstringstream && o, const char * s)
{
return o << s; // note: *not* "std::move(o)"
}
关于c++ - 在 C++ 中将字符串打印到临时流对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8013900/