C++ 通过 copy() 输出

标签 c++ algorithm stl iterator ostream

我正在使用 C++ 和 STL,并且尝试将双端队列复制到列表中并通过 copy() 和 ostream_iterator 打印列表。由于某种原因,除非我通过 front()、back() 或 at() 访问元素,否则我复制到的列表的内容不会打印。为什么前两次打印尝试失败:

#include <iostream>
#include <fstream>
#include  <deque>
#include <algorithm>
#include <iterator>
#include <list>
using namespace std;

void alterParticle(string&);

int main(){

   string tmp_str;
   deque<string> d;
   list<string> l;

   ifstream in("foo.txt");
   if(!in.is_open()){
      cout << "Error opening file" << endl;
      return 1;
   }
   while(in){
      getline(in,tmp_str);
      d.push_back(tmp_str);
   }

   for_each(d.begin(),d.end(),alterParticle);

   copy(d.begin(),d.end(),ostream_iterator<string>(cout,"\n"));

   ostream_iterator<string> out(cout,"\n");
   copy_if(d.begin(),d.end(),out,
         [](const string& s){
            if(s.find("fooparticle")!= string::npos)
               return true;
            return false;
         });

   copy_if(d.begin(),d.end(),l.begin(),
      [](const string& s){
         if(s.find("fooparticle")!= string::npos)
            return true;
         return false;
      });

   cout << "First try: " << endl;
   for(string s : l)
      cout << s << endl;

   cout << "Second try: " << endl;
   copy(l.begin(),l.end(),out);

   cout << "Last try: " << l.front() << endl;

   return 0;
}

void alterParticle(string& s){
   int fpos = s.find("quark");
   string rep_str{"quark"};
   if(fpos != string::npos){
      s.replace(s.find(rep_str),rep_str.length(),"fooparticle");
   }
}

输出:

fooparticle 10 11.4
neutrino 7 20.5
electron 5 6.7
proton 8 9.5

fooparticle 10 11.4
First try:
Second try:
Last try: fooparticle 10 11.4

编辑:

为了更容易理解为什么这对提出相同问题的人不起作用,以下是 copy_if() 的语义。它非常清楚地表明它不会扩展容器:

template <class InputIterator, class OutputIterator, class UnaryPredicate>
  OutputIterator copy_if (InputIterator first, InputIterator last,
                          OutputIterator result, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) {
      *result = *first;
      ++result;
    }
    ++first;
  }
  return result;
}

最佳答案

copycopy_if 不会向 list 添加新元素,它们假定存在要复制到的现有元素。您的列表最初是空的,因此您正在写入列表的 begin() == end() 迭代器。这不会增加列表大小(这就是前两次尝试不打印任何内容的原因),但如果您访问(实际上不存在)第一个列表成员,您可能会得到那里写入的结果。

不用说,分配给 end() 迭代器是未定义的行为。

如果您使用insert_iterator,您可以继续使用copy和 friend 。 (您通常会使用 back_inserter ),类似于您已经使用的 ostream_iterator

关于C++ 通过 copy() 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50334281/

相关文章:

c++ - 如何让代码完成在 Sublime Text 3 中为 c++ 工作?

c++ - 异常后程序不会停止

c++ - 在 std::vector 构造函数中使用 std::string 数据类型

c++ - 根据 C++17 标准,为什么反向迭代器不是正式的迭代器类别?

c++ - C++中的动态缓冲区类型?

c++ - 获取PE头在内存中的虚拟地址

c++ - 这是指向指针的指针吗?

php - 修改后的先序树遍历中的路径

C++ 返回泛型类型集合的正确方法

python - gensim LDA : How can i generate topics with different words for each topic?