问题描述
一个简单的问题,假设我保存了一个包含5个值的集合,并且想将前3个值复制到向量中,是否有一种快速简便的方法? 我知道,如果我想将整个集合复制到向量中,则可以使用如下代码:
set <int> test = {0,1,2,3,4,5};
vector<int> vect(test.begin(),test.end());
我可以做一些类似于仅复制前n个值的操作吗?我一直在使用for循环来执行此操作,但我只是想检查是否有更快的编码方法。
解决方法
要获得从n
的{{1}}到begin
的迭代器,std::set
会产生所需的抽象。
std::next
这是由于std::vector<int> vec(test.cbegin(),std::next(test.cbegin(),5));
提供了双向迭代器,因此您不能使用像std::set
这样的算法。 test.cbegin() + 5
为您解决了这个问题。
std::set::iterator
是一个bidirectional迭代器,而不是random access迭代器,因此使用std::next
`,如下所示
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
int main() {
std::set <int> test = {0,1,2,3,4,5};
size_t n=3;
std::vector<int> vect;
if(test.size() >= n) vect = std::vector<int>{test.begin(),std::next(test.begin(),n)};
std::for_each(vect.begin(),vect.end(),[](auto el){std::cout << el <<" ";});
}
,
std::next()
答案的问题在于std::next()
本质上是不安全的。如果set
中实际上没有5个元素,那么您将不断迭代结束迭代器,这是未定义的行为。
如果您改用range-v3,则这是一种安全且我认为更具表现力的解决方案:
auto vect = test
| views::take(5)
| ranges::to<std::vector>();
这将花费多达集合的前5个元素,并在结果范围之外构造vector
。 views::take
在C ++ 20中,但不幸的是ranges::to
不是。
Demo。