386

Is there something in <algorithm> which allows you to check if a std:: container contains something? Or, a way to make one, for example:

if(a.x == b.x && a.y == b.y)
return true;

return false;

Can this only be done with std::map since it uses keys?

Thanks

5
  • If it contains something specific, or just of it's not empty? Commented Aug 10, 2010 at 15:54
  • 2
    Which C++ reference are you using? And the header is called <algorithm> - note no .h.
    – anon
    Commented Aug 10, 2010 at 15:54
  • Something specific such as a custom struct.
    – jmasterx
    Commented Aug 10, 2010 at 15:56
  • 1
    if the container contains a custom struct, then you'll need to implement operator== to compare them; then std::find will work. Commented Aug 10, 2010 at 16:13
  • Like answered in the duplicate, I think the most elegant is to use boost::algorithm::any_of_equal. Commented Jul 25, 2018 at 10:58

3 Answers 3

721

Checking if v contains the element x:

#include <algorithm>

if(std::find(v.begin(), v.end(), x) != v.end()) {
    /* v contains x */
} else {
    /* v does not contain x */
}

Checking if v contains elements (is non-empty):

if(!v.empty()){
    /* v is non-empty */
} else {
    /* v is empty */
}
9
  • 35
    what if x is the last element in v? Commented Dec 5, 2012 at 1:38
  • 132
    David, end() points to one past the last element, so it all works out. Commented Jan 14, 2013 at 20:08
  • 4
    Does this account for numerical tolerance when trying to determine if a double is in the vector? Commented Aug 20, 2015 at 7:18
  • 21
    @NicholasHamilton: No, it uses operator==. If you need to account for numerical tolerance, use std::find_if and supply a suitable predicate.
    – You
    Commented Aug 20, 2015 at 18:38
  • 1
    @DarnocEloc: No.
    – You
    Commented Aug 6, 2020 at 7:58
142

If searching for an element is important, I'd recommend std::set instead of std::vector. Using this:

std::find(vec.begin(), vec.end(), x) runs in O(n) time, but std::set has its own find() member (ie. myset.find(x)) which runs in O(log n) time - that's much more efficient with large numbers of elements

std::set also guarantees all the added elements are unique, which saves you from having to do anything like if not contained then push_back()....

12
  • 1
    Great!!! I'm writing a lexer. Sets will be much better than vectors. Does set have a count method like map? I also want to be able to get the index of the element in a set.
    – IAbstract
    Commented Apr 3, 2015 at 12:30
  • 4
    Excellent information! Thank you for both answering the straight question and providing an additional solution. Commented Jun 18, 2015 at 3:10
  • 31
    This is bad advice. If performance is important, profile. There is no guarantee whatsoever that complexity analysis has anything to say about your specific problem. Commented Sep 2, 2016 at 11:24
  • 2
    It depends on the number of elements. std::set's lookup characteristics work great for conainers with high number of elements at the cost of data locality. You must perform performance analysis (eg. profiling) to decide how high is high enough to switch from a vector data structure to a set data structure. Commented Oct 3, 2016 at 7:30
  • 4
    @Segmentation The O(n) notation is not about worst cases. AFAIK, set doesn't work like a vector at all. Most set implementations use red-black trees, which have a significant overhead. I don't know what you mean by a header adding overhead. Overhead usually refers to runtime overhead. The best use cases of set are "I'm feeling lazy and don't want to think about it," and "I need to get this done quickly." If you care about performance, you need to profile. unordered_set might be worth trying. Commented Apr 1, 2019 at 9:41
16

See question: How to find an item in a std::vector?

You'll also need to ensure you've implemented a suitable operator==() for your object, if the default one isn't sufficient for a "deep" equality test.

2
  • 1
    I normally wouldn't implement a custom operator==() for my class to just be able to use std::find() once or twice. I would only do that if it actually makes sense to add that override to the public interface of your class. Needing to be able to use std::find() doesn't justify that. Furthermore, what if you need to do std::find() twice but need to compare your objects in a different way? Like on a different property?
    – Jupiter
    Commented Apr 10, 2019 at 22:55
  • if you are worried to implement the operator==, then I would recommend using std::find_if, then you could have re-usable predicates for your different criteria cases
    – yano
    Commented Nov 21, 2019 at 23:57

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.