gpt4 book ai didi

c++ - 如何从 std::vector 或列表中选择一个子集?

转载 作者:可可西里 更新时间:2023-11-01 15:55:12 29 4
gpt4 key购买 nike

C++ 大师:

有很多有用的 c++ STL 算法,例如查找或搜索。然而,他们似乎只返回一个单一的交互器。

如果我想为 STL 容器执行 SQL 样式的“选择”怎么办?比如,一个 vector (可能扩展到列表或 map )。像

std::pair<vector::iterator, vector::iterator> select(std::vector::iterator begin, std::vector::iterator end, Comparor equal_to)

输出应该是一个范围,类似于std::pair,类似于boost::multi-index中方法的返回值

STL里有这样的东西吗?或任何类似的实体库?

最佳答案

基本上有两种方法:

1) 你在上面的评论中所说的,将结果写入(迭代器指向)到迭代器的容器中。这看起来像这样:

template <typename ForwardIterator, typename OutputIterator, typename UnaryPredicate>
void select_iterators(ForwardIterator first, ForwardIterator last,
OutputIterator out, UnaryPredicate pred) {
while (first != last) {
if pred(*first) *out++ = first;
++first;
}
}

然后你这样调用它:

vector<Foo> myfoos;
vector<vector<Foo>::iterator> results;
select_iterators(myfoos.begin(), myfoos.end(), std::back_inserter(results), some_comparator);

您实际上可以根据其他算法定义 select_iterators,使用 copy_ifboost::counting_iterator,但我不认为这是当直接实现如此简单时,这是值得的。它看起来像:

template <typename ForwardIterator, typename OutputIterator, typename UnaryPredicate>
void select_iterators(ForwardIterator first, ForwardIterator last,
OutputIterator out, UnaryPredicate pred) {
std::copy_if(
boost::make_counting_iterator(first),
boost::make_counting_iterator(last),
out,
[&](ForwardIterator it) { return pred(*it); }
);
}

2) 不是预先测试所有值并将结果写在某处,而是定义一个迭代器,每次递增时都会在原始范围内前进,直到找到下一个匹配项。 Boost 提供了两种方法,boost::filter_iteratorboost::adaptors::filter。所以你可以这样写:

auto results = boost::adaptors::filter(myfoos, some_comparator);

然后,无论您想对结果做什么,都可以从 results.begin() 迭代到 results.end(),就好像它是一个容器一样。它不是容器,它不满足整个容器接口(interface)。它满足 Boost 定义的一个接口(interface),名为 Range,相当于“可以迭代”。它实际上只是 myfoos 的过滤 View ,因此没有 Foo 对象被复制甚至移动。

关于c++ - 如何从 std::vector 或列表中选择一个子集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20168483/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com