从组件构建字符串的最佳方法,iostream样式

时间:2015-02-14 05:12:31

标签: c++ string c++11 stringstream

在我的代码中的许多地方,我需要构造可理解的错误消息,但是始终创建字符串流是繁琐的,尤其是当您必须在构造函数的初始化列表中创建字符串时。如果这可以通过一个简单的函数来完成,那么它将使代码更具可读性。

鉴于下面的许多示例用例之一,实现以下createString函数的优雅方法是什么?

struct Base {
    std::string msg;
    Base(const std::string& msg) : msg(msg) { }
};

struct Derived: public Base {
    Derived(int value)
    // Parent constructor requires a string so we have to create it inline
    : Base(createString("This is class " << value))
    { }
};

int main(void)
{
    int i = 5; // some number obtained at runtime
    Derived d(i);
    std::cout << d.msg << "\n";
    return 0;
}

到目前为止,我已经提出了这个C ++ 11版本,但是它有一些缺点(需要预处理器宏,有时字符串必须包含在std::string()等等)所以我想知道是否有人提出了更好的选择?

#include <sstream>
#define createString(a) \
    (static_cast<const std::ostringstream&>(std::ostringstream() << a).str())

1 个答案:

答案 0 :(得分:2)

提供std::stringstream周围的包装,并将其隐式转换为std::string。它稍微改变了语法:

class WrapSStream
{
public:
  template <typename T>
  WrapSStream& operator<<(const T& val)
  {
    ss << val;
    return *this;
  }

  operator string(){return ss.str();}

private: 
  stringstream ss;
};

struct Base {
    string msg;
    Base(const string& msg) : msg(msg) { }
};

struct Derived: public Base {
    Derived(int value)
    // Parent constructor requires a string so we have to create it inline
      : Base(WrapSStream() << "This is class " << value)
    { }
};

int main(void)
{
    int i = 5; // some number obtained at runtime
    Derived d(i);
    cout << d.msg << "\n";
    return 0;
}

输出This is class 5

Live demo