从组件构造字符串的最佳方法,iostream 样式
Best way to construct a string from components, iostream style
在我的代码中的许多地方,我需要构造可理解的错误消息,但始终创建字符串流是乏味的,尤其是当您必须在构造函数的初始化列表中创建字符串时。如果这可以用一个简单的函数来完成,它将使代码的可读性大大提高。
给定以下众多示例用例之一,实现以下 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())
围绕 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
.
在我的代码中的许多地方,我需要构造可理解的错误消息,但始终创建字符串流是乏味的,尤其是当您必须在构造函数的初始化列表中创建字符串时。如果这可以用一个简单的函数来完成,它将使代码的可读性大大提高。
给定以下众多示例用例之一,实现以下 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())
围绕 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
.