考虑以下功能:
void f(const char* str);
Run Code Online (Sandbox Code Playgroud)
假设我想使用stringstream生成一个字符串并将其传递给此函数.如果我想在一个声明中这样做,我可能会尝试:
f((std::ostringstream() << "Value: " << 5).str().c_str()); // error
Run Code Online (Sandbox Code Playgroud)
这给出了一个错误:'str()'不是'basic_ostream'的成员.好的,所以operator <<返回ostream而不是ostringstream - 如何将它转换回ostringstream?
1)这个演员安全吗?
f(static_cast<std::ostringstream&>(std::ostringstream() << "Value: " << 5).str().c_str()); // incorrect output
Run Code Online (Sandbox Code Playgroud)
现在有了这个,结果是运算符<<("Value:")调用,它实际上调用了ostream的运算符<<(void*)并打印了一个十六进制地址.这是错的,我想要的是文字.
2)为什么operator << on临时std :: ostringstream()会调用ostream运算符?当然临时有一种'ostringstream'而不是'ostream'?
我可以施放临时强制执行正确的操作员!
f(static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << "Value: " << 5).str().c_str());
Run Code Online (Sandbox Code Playgroud)
这似乎有效并将"Value:5"传递给f().
3)我现在依赖于未定义的行为吗?演员看起来很不寻常.
我知道最好的选择是这样的:
std::ostringstream ss;
ss << "Value: " << 5;
f(ss.str().c_str());
Run Code Online (Sandbox Code Playgroud)
...但我对在一行中做这件事的行为很感兴趣.假设有人想制作一个(可疑的)宏:
#define make_temporary_cstr(x) (static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << x).str().c_str())
// ...
f(make_temporary_cstr("Value: " << 5));
Run Code Online (Sandbox Code Playgroud)
这会按预期运作吗?