C ++简洁地检查STL容器中的项目(例如向量)

时间:2014-10-03 20:39:07

标签: c++ boost stl

bool xInItems = std::find(items.begin(), items.end(), x) != items.end();

是否有更简洁的方法来检查x是否在物品中?这似乎不必要地冗长(重复项目三次),这使得代码的意图有点难以阅读。

例如,是否有以下内容:

bool xInItems = boost::contains(items, x);

如果不存在任何更简洁的boost / stl算法来检查集合是否包含项目,那么使用辅助函数来启用contains(items, x)是否被视为好或坏做法?

我使用错误的STL容器吗?即使是std :: set也会导致bool xInItems = items.find(x) != items.end();仍然显得冗长。我是否以错误的方式思考这个问题?

6 个答案:

答案 0 :(得分:5)

从头开始编写模板函数并不难。

template<typename T, typename Iterator>
bool contains(Iterator it1, Iterator it2, const T & value)
{
    return std::find(it1, it2, value) != it2;
}

template<typename T, typename Container>
bool contains(const Container & c, const T & value)
{
    return contains(c.begin(), c.end(), value);
}

您甚至可以为拥有find功能的容器提供专业化服务,这样就不会调用std::find

答案 1 :(得分:3)

documentation将完成任务:

#include <boost/algorithm/cxx11/any_of.hpp>

bool xInItems = boost::algorithm::any_of_equal(items, x);

答案 2 :(得分:1)

如果您的数据已排序,您可以使用std::binary_search,它会返回bool

bool xInItems = std::binary_search(items.begin(), items.end(), x));

如果你确实需要保留未排序的项目但是C ++ 11可用,你可以使用std::any_of,但它需要一个谓词,所以它可能至少会结束像std::find一样详细(可能更多)。

答案 3 :(得分:0)

查找元素是否在集合中的一种简单方法是:

container.find(x) != container.end()

因此,如果要使用一组整数,则可能类似于:

stl::set<int> intSet;
intSet.insert(3);
if( intSet.find(3) != intSet.end()) 
      printf("Found it!");

答案 4 :(得分:0)

#include "boost/range/algorithm/find.hpp"

bool xInItems = boost::find(items, x) != items.end();

考虑到C ++中灵活的迭代器使用的偏好,这是应该预期的简洁。

您应该坚持使用std :: find,因为它是惯用的,并且希望最终std::range将被接受并为迭代器对提供标准的更简洁的替代。

答案 5 :(得分:0)

C++20 stl 容器 setmapunordered_map 具有 contains 方法:

bool xInItems = items.contains(x);

遗憾的是,并非所有容器都如此,因此对于 vectorlist,您仍然必须按照您的方式编写它(或者像 Mark 的那样包装到一个函数中)很好的答案)。