【问题标题】:How to use an ostringstream in just an expression如何在表达式中使用 ostringstream
【发布时间】:2018-08-17 16:38:56
【问题描述】:

我使用std::ostringstream 格式化字符串,它从ostream 继承其<< 运算符,因此它们返回ostream 而不是ostringstream,这意味着我不能调用ostringstream::str结果上。这通常不是问题,因为我通常可以这样做:

ostringstream stream;
stream << whatever;
string str = stream.str();

但有时我需要*在一个表达式中使用它,这比较困难。我可以的

string str = ((ostringstream&) (ostringstream() << whatever)).str();

但如果 &lt;&lt; 重载返回一些不是 ostringstreamostream,就会发生不好的事情。我唯一能想到的其他事情就是

string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();

但这不可能是高效的,而且肯定是非常糟糕的 c++ 代码。


*好吧,我不需要,但是这样会方便很多。

【问题讨论】:

  • 如果该重载返回的不是它所提供的流,我会认为它完全损坏并丢弃它。
  • @molbdnilo 除非whatever 是(或包括)出于某种原因应该这样做的操纵者。
  • @Justin 这是一个成语,说明这种语言有些不讨人喜欢。
  • @Anonymous Manipulators 更改正在作用的流对象听起来仍然很糟糕。

标签: c++ ostringstream


【解决方案1】:

使用

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

【讨论】:

    【解决方案2】:

    我能想到的唯一其他事情就是

    string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();
    

    但这不可能是有效的,而且肯定是非常糟糕的 c++ 代码。

    实际上,没有。一旦优化器看到这个,它就和原始代码一样快。这不是“非常糟糕的 C++ 代码”。它被称为立即调用的 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();
    });
    

    【讨论】:

    • 我认为你应该提到 std::invoke 是 c++17
    【解决方案3】:

    假设你得到了

    std::string get_str(std::ostream& out) {
        retrun static_cast<std::stringbuf*>(out.rdbuf())->str();
    }
    

    你可以使用

    std:: string s = get_str(std::ostringstream{} << ...);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 2020-05-07
      • 2016-03-31
      • 1970-01-01
      相关资源
      最近更新 更多