标签: iterator

停止在最后一个元素迭代器C++上

在第二个到最后一个元素之后执行循环并停止的最优雅方式是什么(在C++ 11中)?

注意:我的意思是双向迭代器; 随机访问迭代器是一个微不足道的特例,当然,因为它们有+-运算符.

std::list<double> x{1,2,3,4,5,6};

for (auto iter = x.begin(); iter != x.end(); ++iter) {
  auto iter2 = iter;
  ++iter2;
  if (iter2 == x.end()) break;
  std::cout << *iter << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

c++ iterator c++11

7
推荐指数
2
解决办法
1542
查看次数

为什么java中的Collections的fill(),copy(),reverse()和shuffle()以这种方式实现

根据javadoc ... Collections.fill()编写如下:

public static <T> void fill(List<? super T> list, T obj) {
        int size = list.size();

        if (size < FILL_THRESHOLD || list instanceof RandomAccess) {
            for (int i=0; i<size; i++)
                list.set(i, obj);
        } else {
            ListIterator<? super T> itr = list.listIterator();
            for (int i=0; i<size; i++) {
                itr.next();
                itr.set(obj);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

很容易理解他们为什么不使用listIterator

if (size < FILL_THRESHOLD || list instanceof RandomAccess) 
Run Code Online (Sandbox Code Playgroud)

条件为RandomAccess.但是size < FILL_THRESHOLD上面的使用是什么?

我的意思是使用iteratorfor size>=FILL_THRESHOLD而不是for for 有任何显着的性能优势size < FILL_THRESHOLD吗?

我也看到了Collections.copy()的相同方法: …

java collections performance iterator list

7
推荐指数
1
解决办法
940
查看次数

获取迭代器范围的每个第n个元素

是否有一个迭代器的标准实现(意思是stdlib或boost)包装另一个迭代器并且只给出它的每个第n个元素?

我首先想到的是,使用拟合谓词和boost :: filter_iterator是可能的,但是谓词只获取值而不是基本迭代器,所以它无法告诉起始距离.

编辑
提供更多信息:迭代器应与std::transform或等函数兼容std::copy.所以它应该像stdlib迭代器一样使用.

类似的问题:
C++/STL:std :: transform与给定的步幅?
非单元迭代器使用非随机访问迭代器

c++ boost iterator std

7
推荐指数
2
解决办法
2363
查看次数

Vector Iterator:'operator ='不匹配

考虑下面第一个代码片段中的代码C++,我得到第二个代码段中指示的编译错误.看起来我在遍历矢量实例时做错了.你能告诉我如何克服这些编译问题吗?谢谢.代码中标记了LINE 171.

SNIPPET 1(代码)

#include <string>
#include <vector>
#include <iterator>

class VipAddressSetEntity : BaseEntity
{
public:
      VipAddressSetEntity() : BaseEntity() { }
      VipAddressSetEntity(std::string &uuid, std::string &name) : BaseEntity(uuid, name) { }

      VipAddressSetEntity(const VipAddressSetEntity &copyin)
      {
       setUUID(copyin.getUUID());
       setName(copyin.getName());

       std::vector<VipAddressEntity>::iterator iter;
               /* LINE 171 is the following*/
       for( iter = copyin.mVipAddressList.begin(); iter !=   copyin.mVipAddressList.end(); iter++ )
       {
                addVipAddress(*iter);
       }
      }

      VipAddressSetEntity operator = (const VipAddressSetEntity &rhs)
      {
        setUUID(rhs.getUUID());
        setName(rhs.getName());

        std::vector<VipAddressEntity>::iterator iter;
        for( iter = rhs.mVipAddressList.begin(); iter != rhs.mVipAddressList.end(); iter++ )
        {
                addVipAddress(*iter);
        } …
Run Code Online (Sandbox Code Playgroud)

c++ iterator stdvector

7
推荐指数
1
解决办法
9890
查看次数

使用erase和insert替换向量中的元素

void replace(vector<string> my_vector_2, string old, string replacement){

    vector<string>::iterator it;
    for (it = my_vector_2.begin(); it != my_vector_2.end(); ++it){

        if (*it==old){
            my_vector_2.erase(it);
            my_vector_2.insert(it,replacement);

        }
    }

}
Run Code Online (Sandbox Code Playgroud)

所以,我希望这个函数用字符串替换替换向量中所有出现的字符串old.但是在调用此函数时,根本不会更改向量.我不确定我是否正确使用擦除和插入功能.有任何想法吗?

c++ iterator insert vector erase

7
推荐指数
2
解决办法
2万
查看次数

STL填充和转发迭代器

根据大多数C++引用,例如cplusplus.com,前向迭代器不需要是可赋值的(我的意思是,引用左值).但是,对于需要写入值的几个STL算法std::fill(例如std::generate等),规范使用了前向迭代器:

template <class ForwardIterator, class T>
  void fill (ForwardIterator first, ForwardIterator last, const T& val);
Run Code Online (Sandbox Code Playgroud)

而等效行为需要左值取消引用:

template <class ForwardIterator, class T>
  void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
  while (first != last) {
    *first = val;
    ++first;
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,它实际上是使用一个可变的前向迭代器和一次传递.

现在的问题是:

(1)为什么不明确这些情况下使用的前向迭代器是否可变?

(2)更新:我发现以下问题是愚蠢的:我暂时忘记了输出迭代器不需要支持相等比较.无论如何,上述问题仍然存在.

为什么使用前向迭代器,而不是输出迭代器std::fill,std::generate等等,而他们实际上并不需要多遍?(std::copy例如,只需要输出迭代器.基本原理是什么?)

c++ iterator stl

7
推荐指数
1
解决办法
2056
查看次数

为什么他使用"typedef vector <double> :: size_type"而不是使用"int"

我只是学习C++而我正在使用Accelerated C++.

在向量示例中,编写器使用以下代码;

typedef vector<double>::size_type vec_sz;
vec_sz size = homework.size;
Run Code Online (Sandbox Code Playgroud)

我知道typedef vector<double>::size_type vec_sz;是这样他不必写下一个命令vector<double>::size_type size = homework.size;,但我的问题是为什么他不是只是声明size为整数?

int size = homework.size;
Run Code Online (Sandbox Code Playgroud)

这是因为我们正在使用向量吗?

如果是这样,这是否意味着向量迭代器返回的值不能存储在常规变量中?

c++ iterator typedef vector

7
推荐指数
2
解决办法
720
查看次数

std :: list和std :: for_each:我的结局在哪里?

请考虑以下最小示例:

#include <functional>
#include <algorithm>
#include <list>

int main() {
    std::list<std::function<void()>> list;
    list.push_back([&list](){ list.push_back([](){ throw; }); });
    std::for_each(list.cbegin(), list.cend(), [](auto &&f) { f(); });
}
Run Code Online (Sandbox Code Playgroud)

它在运行时编译并抛出异常.
我的猜测是只有第一个lambda被执行std::for_each,但显然我错了:如果我在列表的末尾添加另一个lambda,迭代也会达到lambda.

让我们恢复示例(push_front而不是push_backcrbegin/ crend而不是cbegin/ cend):

#include <functional>
#include <algorithm>
#include <list>

int main() {
    std::list<std::function<void()>> list;
    list.push_front([&list](){ list.push_front([](){ throw; }); });
    std::for_each(list.crbegin(), list.crend(), [](auto &&f) { f(); });
}
Run Code Online (Sandbox Code Playgroud)

由于前面的例子,我预计这也会编译和崩溃.
相反,它编译并且不会崩溃.这次,不执行推到列表前面的功能.

问题很简单:这是正确的吗?
为什么两个例子如此违反直觉?

在第一种情况下,我期待一些不同的东西,我错了,这不是问题.
无论如何,我希望两个循环之间的一致性.我的意思是,第二个函数在一个案例中执行,而在另一个案例中不执行,但我在两种情况下都是从开始结束迭代.
我的推理出了什么问题?

c++ foreach iterator stdlist

7
推荐指数
1
解决办法
426
查看次数

是否可以使用`std :: set_intersection`来检查两个集合是否有任何共同的元素?

std::set_intersection允许我std::set通过输出元素到输出迭代器来检索两个实例之间的所有共同元素.在我的特殊情况下,我只想检查两组是否有任何共同的元素.

我目前的解决方案是使用如下boost::function_output_iterator设置bool变量:

bool b{false};
set_intersection(begin(s0), end(s0),
                 begin(s1), end(s1),
                 make_function_output_iterator([&](const auto&){ b = true; }));
return b;
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果找到匹配项,此解决方案不会提前返回:必须完全遍历集合(即没有提前返回/短路).

是否可以set_intersection提前退货?我能想到的唯一解决方案是从function_output_iterator 函数对象中抛出异常,这是一个可怕的想法.

如果没有,标准库中还有什么可以帮助我,还是我被迫重新实现set_intersection?额外的问题:set_intersection如果它允许提前终止(即标准库算法可能具有的"最通用"接口),界面会如何

c++ iterator stl set c++17

7
推荐指数
1
解决办法
865
查看次数

从std :: copy和std :: copy_n中提取输入迭代器

我试图实现一个反序列化方法,它接受一个输入迭代器并执行一系列块读取(使用std::copystd::copy_n).像这样的东西(只是一个例子):

template <class InputIt>
InputIt unserialize(InputIt it)
{
  std::copy_n(it, sizeof(header_type), reinterpret_cast<char*>(&header));
  std::copy_n(it, header.payload_size, std::back_inserter(payload));
  it = optional.unserialize(it);
  return it;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下如何提前输入迭代器,以便每次跟随调用std::copy_n继续从中读取并最终返回它?

出于性能原因,我希望对迭代器类别(尤其是RandomAccessIterator和InputIterator)具有通用性,并希望可以使用std::copy方法而无需重写这些方法.像绑定检查这样的东西将由迭代器适配器完成,或者如果已知大小,则在反序列化调用之前检查.

什么不起作用也不可接受:

  1. 使用std::copy_n<InputIt&>(it, ...)可能适用于某些类别但不适用于所有类别,并且它太不可靠.
  2. std::advance在每次调用之后使用会导致为某些迭代器重新读取相同的块.不是优选的,对某些来源可能是不可能的.

UPDATE使得迭代器引用适配器没有帮助,因为随机访问迭代器版本的copy_n返回指针超过复制的最后一个元素,而输入迭代器版本返回指向复制的最后一个元素的指针.所以我想自己的版本copy_n最适合使用额外的迭代器适配器进行绑定检查.

c++ iterator stl

7
推荐指数
1
解决办法
377
查看次数

标签 统计

iterator ×10

c++ ×9

stl ×3

vector ×2

boost ×1

c++11 ×1

c++17 ×1

collections ×1

erase ×1

foreach ×1

insert ×1

java ×1

list ×1

performance ×1

set ×1

std ×1

stdlist ×1

stdvector ×1

typedef ×1