我试图想出一种聪明的方法,将各种事物连接成一个函数的单个字符串参数,而不必ostringstream显式使用.我想到了:
#define OSS(...) \
dynamic_cast<std::ostringstream const&>(std::ostringstream() << __VA_ARGS__).str()
Run Code Online (Sandbox Code Playgroud)
但是,鉴于:
void f( string const &s ) {
cout << s << endl;
}
int main() {
char const *const s = "hello";
f( OSS( '{' << s << '}' ) );
ostringstream oss;
oss << '{' << s << '}';
cout << oss.str() << endl;
}
Run Code Online (Sandbox Code Playgroud)
运行时打印:
123hello}
{hello}
Run Code Online (Sandbox Code Playgroud)
其中123是ASCII码}.为什么使用宏会弄错?
仅供参考:我目前在Mac OS X上使用g ++ 4.2.1作为Xcode 3.x的一部分.
class string_builder {
public:
template<typename T>
string_builder& operator,( T const &t ) {
oss_ << t;
return *this;
}
operator std::string() const {
return oss_.str();
}
private:
std::ostringstream oss_;
};
#define BUILD_STRING(...) (string_builder(), __VA_ARGS__)
using namespace std;
void f( string const &s ) {
cout << s << endl;
}
int main() {
char const *const s = "hello";
f( BUILD_STRING( '{', s, '}' ) );
}
Run Code Online (Sandbox Code Playgroud)
std::ostringstream()是临时的,因此只能绑定到const引用.不考虑独立运算符<<(将非const引用作为第一个参数),仅考虑成员1.这些对char的最佳匹配是将char转换为int.
这些问题经常发生在字符串文字中,然后显示其地址.
要解决这个问题,诀窍是找到一种方法来转换引用中的临时值.成员operator<<s这样做,但只有操纵器的那个没有副作用,并且只有当操纵器是noop时才可以使用 - 冲洗.成员刷新和写作也是候选人.所以举个例子
#define OSS(...) \
dynamic_cast<std::ostringstream const&>(std::ostringstream().flush() << __VA_ARGS__).str()
Run Code Online (Sandbox Code Playgroud)