【问题标题】:How do you use the extraction operator (>>) with vector<bool>?如何将提取运算符 (>>) 与 vector<bool> 一起使用?
【发布时间】:2015-08-18 07:53:45
【问题描述】:

vector&lt;int&gt; someVectoristringstream someStringStream 的示例中,您可以这样做:

for (int i=0; i < someVector.size(); i++) {
  someStringStream >> someVector[i];
}

我知道vector&lt;bool&gt; 是一个高效的实现,operator[] 返回一个引用对象。 对于这段代码,我应该使用索引而不是迭代器,主要是为了可读性。 目前,我正在使用这个:

for (int i=0; i < someVector.size(); i++) {
  bool temp;
  someStringStream >> temp;
  someVector[i] = temp;
}

有没有更直接的实现方式?

【问题讨论】:

    标签: c++ c++11 vector extraction-operator


    【解决方案1】:

    如果您想使用整个流,可以使用std::copystd::vector 范围构造函数:

    std::stringstream ss("1 0 1 0");
    std::vector<bool> vec;
    std::copy(std::istream_iterator<bool>(ss), {}, std::back_inserter(vec));
    

    LIVE DEMO

    std::stringstream ss("1 0 1 0");
    std::vector<bool> vec(std::istream_iterator<bool>(ss), {});
    

    LIVE DEMO

    现在查看您发布的示例,如果您确定您的 std::vectors 大小合适,您可以使用 std::generate,如下例所示:

    std::stringstream ss("1 0 1 0");
    std::vector<bool> vec(4);
    std::generate(std::begin(vec), std::end(vec), [&ss](){ bool val; ss >> val; return val;});
    

    LIVE DEMO

    【讨论】:

      【解决方案2】:

      如果你想要的只是 bool 和其他类型的相同接口,那么包装很容易。

      template <typename T>
      T read(std::istream& stream)
      {
         T value;
         stream >> value; // TODO: guard against failure of extraction, e.g. throw an exception.
         return value;
      }
      

      但是,直接使用它需要你指定一个类型。

      for (int i=0; i < someIntVector.size(); i++)
      {
         someIntVector[i] = read<int>(someStringStream);
      }
      
      for (int i=0; i < someBoolVector.size(); i++)
      {
         someBoolVector[i] = read<bool>(someStringStream);
      }
      

      如果你对几个不同的向量重复使用它,只需再次包装它:

      template <typename T, typename A>
      void fillVectorFromStream(std::istream& stream, std::vector<T, A>& vector)
      {
          for ( int i = 0; i < vector.size(); ++i )
          {
              vector[i] = read<T>(stream);
          }
      }
      

      因此,用法就变成了

      fillVectorFromStream(streamOfBool, vectorOfBooleanValues);
      fillVectorFromStream(streamOfIntegers, vectorOfIntegers);
      

      【讨论】:

      • 这不安全。如果运算符 >> 失败,则“值”将未初始化。应该明确检查流状态,或者应该将 std::ios_base::failbit 与流的 exceptions() 进行 ORed。
      • @ArneVogel 这在 C++11 中有所改变:如果提取失败,则将零写入值(请参阅 en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt)。但是,我确实同意在生产代码中需要进行错误检查。尽管如此,有很多方法可以做到这一点。选择一个不是问题的范围,恕我直言。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 2016-06-28
      • 1970-01-01
      • 2021-06-16
      • 2011-07-29
      • 2019-01-17
      相关资源
      最近更新 更多