如何在表达式中使用 ostringstream
How to use an ostringstream in just an expression
我使用 std::ostringstream
来格式化字符串,它从 ostream
继承了它的 <<
运算符,因此它们 return 是 ostream
而不是 ostringstream
,这意味着我无法对结果调用 ostringstream::str
。这通常不是问题,因为我通常可以这样做:
ostringstream stream;
stream << whatever;
string str = stream.str();
但偶尔我需要*只在一个表达式中使用它,这比较困难。我可以
string str = ((ostringstream&) (ostringstream() << whatever)).str();
但如果 <<
超载 return 一些 ostream
不是 ostringstream
,就会发生不好的事情。我唯一能想到的另一件事就是
string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();
但这不可能是高效的,而且肯定是非常糟糕的 c++ 代码。
*好吧,我不需要,但这样会方便很多。
The only other thing I can think to do is something like
string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();
but this can't possibly be efficient, and is certainly very bad c++
code.
实际上,没有。一旦优化器查看了它,它就会和原始代码一样快。它不是 "very bad c++ code"。它被称为立即调用的 Lambda 表达式或 IILE。这是一个成语,实际上是相当不错的做法。
虽然格式更像这样会更好:
// One of the benefits of IILEs is that `const` can be used more frequently
string const str = [&] {
ostringstream stream;
stream << whatever;
return stream.str();
}();
有些人更喜欢使用 std::invoke
来调用 lambda:
string const str = std::invoke([&] {
ostringstream stream;
stream << whatever;
return stream.str();
});
使用
string str = ([&] () -> string
{
ostringstream stream;
stream << whatever;
return stream.str();
})();
没问题。但是,我认为最好为该操作命名,创建一个具有该名称的函数,然后调用该函数。
namespace MyApp
{
template <typename T>
std::string to_string(T const& t)
{
ostringstream stream;
stream << t;
return stream.str();
}
}
然后使用
string str = MyApp::to_string(whatever);
假设你有
std::string get_str(std::ostream& out) {
retrun static_cast<std::stringbuf*>(out.rdbuf())->str();
}
你可以使用
std:: string s = get_str(std::ostringstream{} << ...);
我使用 std::ostringstream
来格式化字符串,它从 ostream
继承了它的 <<
运算符,因此它们 return 是 ostream
而不是 ostringstream
,这意味着我无法对结果调用 ostringstream::str
。这通常不是问题,因为我通常可以这样做:
ostringstream stream;
stream << whatever;
string str = stream.str();
但偶尔我需要*只在一个表达式中使用它,这比较困难。我可以
string str = ((ostringstream&) (ostringstream() << whatever)).str();
但如果 <<
超载 return 一些 ostream
不是 ostringstream
,就会发生不好的事情。我唯一能想到的另一件事就是
string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();
但这不可能是高效的,而且肯定是非常糟糕的 c++ 代码。
*好吧,我不需要,但这样会方便很多。
The only other thing I can think to do is something like
string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();
but this can't possibly be efficient, and is certainly very bad c++ code.
实际上,没有。一旦优化器查看了它,它就会和原始代码一样快。它不是 "very bad c++ code"。它被称为立即调用的 Lambda 表达式或 IILE。这是一个成语,实际上是相当不错的做法。
虽然格式更像这样会更好:
// One of the benefits of IILEs is that `const` can be used more frequently
string const str = [&] {
ostringstream stream;
stream << whatever;
return stream.str();
}();
有些人更喜欢使用 std::invoke
来调用 lambda:
string const str = std::invoke([&] {
ostringstream stream;
stream << whatever;
return stream.str();
});
使用
string str = ([&] () -> string
{
ostringstream stream;
stream << whatever;
return stream.str();
})();
没问题。但是,我认为最好为该操作命名,创建一个具有该名称的函数,然后调用该函数。
namespace MyApp
{
template <typename T>
std::string to_string(T const& t)
{
ostringstream stream;
stream << t;
return stream.str();
}
}
然后使用
string str = MyApp::to_string(whatever);
假设你有
std::string get_str(std::ostream& out) {
retrun static_cast<std::stringbuf*>(out.rdbuf())->str();
}
你可以使用
std:: string s = get_str(std::ostringstream{} << ...);