C++ concisely checking if item in STL container (e.g. vector)

≡放荡痞女 提交于 2019-12-22 05:49:16

问题


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

Is there a more concise way of checking if x is in items? This seems unnecessarily verbose (repeating items three times), which makes the intent of the code a little harder to read.

For example, is there something like the following:

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

If there doesn't exist any more concise boost/stl algorithm to check if a collection contains an item, is it considered good or bad practice to use instead a helper function to enable contains(items, x)?

Am I using the wrong STL container? Even a std::set would result in bool xInItems = items.find(x) != items.end(); which still seems verbose. Am I thinking about this the wrong way?


回答1:


If your data is sorted, you can use std::binary_search, which returns a bool:

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

If you really need to leave the items un-sorted, but have C++11 available, you could use std::any_of, but it requires a predicate, so it's likely to end up at least as verbose as std::find (and probably more so).




回答2:


It's not hard to write a template function from scratch.

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);
}

You can even provide specializations for containers that have their own find function so that it's not calling std::find.




回答3:


any_of_equal will do the task:

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

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



回答4:


One easy way to find if an element is within a set is with:

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

So that if you are to use a set of integers, it could be something like:

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



回答5:


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

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

This is as concise as should be expected given the preference towards flexible iterator usage in C++.

You should probably just stick with std::find since it is idiomatic, and hope that eventually std::range will be accepted and provide a standard more concise alternative to iterator pairs.



来源:https://stackoverflow.com/questions/26186483/c-concisely-checking-if-item-in-stl-container-e-g-vector

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!