c++ - ostringstream 的奇怪行为

标签 c++ ostringstream

我试图想出一种聪明的方法来将各种东西连接到一个函数的单个字符串参数中,而不必显式使用 ostringstream。我想到了:

#define OSS(...) \
  dynamic_cast<std::ostringstream const&>(std::ostringstream() << __VA_ARGS__).str()

但是,给定:

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;
}

运行时打印:

123hello}
{hello}

其中 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, '}' ) );
}

最佳答案

std::ostringstream()是临时的,因此只能绑定(bind)到 const 引用。独立运算符<<(将非常量引用作为第一个参数)不被考虑,只有成员一个被考虑。其中与 char 的最佳匹配是将 char 转换为 int。

此问题经常发生在随后显示其地址的字符串文字上。

要解决这个问题,诀窍是找到一种方法来转换引用中的临时对象。成员(member)operator<<我们这样做,但只有操纵器的那个没有副作用,并且只有当操纵器是一个 noop 时才可以使用 flush。成员 flush 和 write 也是候选人。比如

#define OSS(...) \
    dynamic_cast<std::ostringstream const&>(std::ostringstream().flush() << __VA_ARGS__).str()

关于c++ - ostringstream 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5666678/

相关文章:

c++ - 如何连接 Boost 序列化和 iostream 以将对象序列化和 gzip 到字符串?

c++ - CoRegisterClassObject 破坏线程安全

c++ - std::find_end 作为 Big-O 的复杂性

c++ - 如何在 C++ 中正确使用 ostringstream?

c++ - 如何在没有 C++ 拷贝的情况下从 ostringstream 获取 char 指针

c++ - std::ostringstream 未返回有效字符串

c++ - 如何检查 C++ 中的大数是否被 7 除?

c++ - UWP C# 应用程序调用用 C++ 编写的 Windows 运行时组件

c++ - 带有 SDL2 的 OpenGL 没有返回正确的版本

C++ ostringstream 奇怪的行为