namespace detail
{
template<int Level> struct select_overload;
template<> struct select_overload<0>{};
template<int Level> struct select_overload : select_overload<Level-1>{};
template<typename C, typename V>
auto contains(C&& c, V&& v, select_overload<1>) -> decltype(c.find(forward<V>(v)) == c.end()) {
BARK;
return c.find(forward<V>(v)) != c.end();
}
template <typename Container, typename Value>
bool contains(const Container& container, const Value& value, select_overload<0>)
{
BARK;
return std::find(std::begin(container), std::end(container), value) != std::end(container);
}
}
template<typename C, typename V>
bool contains(C&& c, V&& v)
{
return detail::contains(forward<C>(c), forward<V>(v), detail::select_overload<1>{});
}
https://wandbox.org/permlink/0DF1muaWEGZkEv0l
To powinno działać i być zgodne z C++11.
Oryginalny post
Tak na szybko:
namespace detail
{
template<typename C, typename V>
auto contains(C&& c, V&& v) -> decltype(c.find(forward<V>(v)) == c.end()) {
BARK;
return c.find(forward<V>(v)) != c.end();
}
template <typename Container, typename Value>
bool contains(const Container& container, const Value& value)
{
BARK;
return std::find(std::begin(container), std::end(container), value) != std::end(container);
}
}
template<typename C, typename V>
bool contains(C&& c, V&& v)
{
return detail::contains(forward<C>(c), forward<V>(v));
}
https://wandbox.org/permlink/RjkyEmaaKihZMu6L
Przy czym to nie jest rozwiązanie idealne, bo czasem zły szablon może być uznany za lepszy:
const set<int> s{1,2,3};
const int i = 1;
contains(s, i); // wybierze złą funkcję