1

I would like to have a template function contains which has two possible definitions, depending on the second type:

template <typename ElementType, typename CollectionType>
bool contains(const CollectionType & collection, ElementType element)
{
    return collection.end() != std::find(collection.begin(), collection.end(), element);
}

and

template <typename CollectionType, typename PredicateType>
bool contains(const CollectionType & collection, PredicateType predicate)
{
    return collection.end() != std::find_if(collection.begin(), collection.end(), predicate);
}

The standard library often uses _if to distinguish predicate from value versions of algorithms - such as find and find_if.

Ideally, I'd like the compiler to figure out which one to use. After all, the above two templates are intended for very different uses - the types of ElementType and PredicateType are pretty different domains.

Is there a good way to accomplish this via template shenanigans? Or am I stuck with finding two different names for the above contains functions?

Mordachai
  • 9,412
  • 6
  • 60
  • 112
  • 3
    What if your container contains predicates? – Kerrek SB Feb 24 '14 at 16:01
  • Good point. Perhaps this cannot be solved without an explicit difference in names. – Mordachai Feb 24 '14 at 16:08
  • 1
    Not sure but using `std::enable_if, ElementType>::type` as the `ElementType` in the first case may remove ambiguity. – Kiwi Feb 24 '14 at 16:23
  • There's got to be a way to come at it from detecting if it is a predicate - i.e. a callable entity... when I have a moment, I'll see if I can make headway from that angle... – Mordachai Aug 17 '16 at 20:50

1 Answers1

4

If your containers play nice and define member value_types, then you could make the "element" overload more specific:

template <typename C>
bool contains(C const & collection, typename C::value_type const & element);

template <typename C, typename P>
bool contains(C const & collection, P predicate);

More arcane approaches might be checking if the container defines begin/end functions and deriving the element type from those. In general it's fairly tricky to decide whether a given type is a container...

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • This sort of approach always almost works for me. Too often I find that I'm trying to detect if a collection contains something that is comparable, but isn't the exact type contained. Hence it tries to resolve to the second template, and fails. :( – Mordachai Feb 25 '14 at 21:44
  • @Mordachai: The [pretty printer code](http://stackoverflow.com/questions/4850473/pretty-print-c-stl-containers) tries to be a bit more clever about what's a container, if that's any help... – Kerrek SB Feb 25 '14 at 22:14