"contains" function for STL containers I have made a simple program that tests if the given element exists in any STL container. The program tests if the container has a find member function. It will use it if it does. Otherwise, it will call the STL find function instead. I would like to know how I can improve it further?

#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;utility&gt;
#include &lt;map&gt;
#include &lt;set&gt;
#include &lt;vector&gt;
#include &lt;array&gt;
#include &lt;type_traits&gt;

template &lt;typename C&gt; decltype(std::declval&lt;C&gt;().find(0), std::true_type{}) test(int);
template &lt;typename C&gt; std::false_type test(...);
template &lt;typename C&gt; using has_find = decltype(test&lt;C&gt;(0));

template &lt;bool B, typename T, typename F&gt;
std::enable_if_t&lt;std::integral_constant&lt;bool, B&gt;::value, T&gt;
conditional(T&amp;&amp; t, F&amp;&amp;)
{
    return std::forward&lt;T&gt;(t);
}

template &lt;bool B, typename T, typename F&gt;
std::enable_if_t&lt;!std::integral_constant&lt;bool, B&gt;::value, F&gt;
conditional(T&amp;&amp;, F&amp;&amp; f)
{
    return std::forward&lt;F&gt;(f);
}

template &lt;typename C, typename T&gt;
auto contains(const C&amp; container, const T&amp; key)
{
    static auto first = [] (auto&amp;&amp; c, auto&amp;&amp; k)
    {
        return c.end() != c.find(k);
    };

    static auto second = [] (auto&amp;&amp; c, auto&amp;&amp; k)
    {
        return c.end() != std::find(c.begin(), c.end(), k);
    };

    auto op = conditional&lt;has_find&lt;C&gt;::value&gt;(first, second);

    return op(container, key);
}

int main()
{
    std::cout &lt;&lt; std::boolalpha;

    std::array&lt;int, 3&gt; a = {{ 1, 2, 3 }};
    std::cout &lt;&lt; contains(a, 0) &lt;&lt; "\n";
    std::cout &lt;&lt; contains(a, 1) &lt;&lt; "\n\n";

    std::vector&lt;int&gt; v = { 1, 2, 3 };
    std::cout &lt;&lt; contains(v, 0) &lt;&lt; "\n";
    std::cout &lt;&lt; contains(v, 1) &lt;&lt; "\n\n";

    std::set&lt;int&gt; s = { 1, 2, 3 };
    std::cout &lt;&lt; contains(s, 0) &lt;&lt; "\n";
    std::cout &lt;&lt; contains(s, 1) &lt;&lt; "\n\n";

    std::map&lt;int, int&gt; m = { { 1, 1}, { 2, 2}, { 3, 3} };
    std::cout &lt;&lt; contains(m, 0) &lt;&lt; "\n";
    std::cout &lt;&lt; contains(m, 1) &lt;&lt; "\n";
}
If you like new features, and even experimental features, you can make your code a lot cleaner. 

Concepts

A lot of those arcane SFINAE techniques will be obsolete once concepts are out, and concepts are already available in an experimental state with the last versions of gcc (enable them with the -fconcepts option):

template &lt;typename Container, typename Value&gt;
concept bool HasFindFunction = requires(Container c, Value v) {
    c.find(v);
};


... and that's it for your trait. 

if constexpr

To specialize the contains function, you can rely on C++17 if constexpr. It's a compile-time if, in which only the chosen branch has to be well-formed. So, here's what you could write:

template &lt;typename Container, typename Value&gt;
auto find(Container&amp;&amp; cont, Value&amp;&amp; val) {
    if constexpr (HasFindFunction&lt;Container, Value&gt;) {
        std::cout &lt;&lt; "member find\n";
        return cont.find(val);
        }
    else { 
        std::cout &lt;&lt; "algorithm find\n";
        return std::find(std::begin(cont), std::end(cont), val);
    }
}


I replace contains by find, because I find it a pity to make a hard won information (the item position) go to waste. You can then write contains on top of it.

Complete working example (g++ prog.cc -Wall -Wextra -std=gnu++2a -fconcepts)

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;map&gt;
#include &lt;algorithm&gt;

template &lt;typename Container, typename Value&gt;
concept bool HasFindFunction = requires(Container c, Value v) {
    c.find(v);
};

template &lt;typename Container, typename Value&gt;
auto find(Container&amp;&amp; cont, Value&amp;&amp; val) {
    if constexpr (HasFindFunction&lt;Container, Value&gt;) {
        std::cout &lt;&lt; "member find\n";
        return cont.find(val);
        }
    else {
        std::cout &lt;&lt; "algorithm find\n";
        return std::find(std::begin(cont), std::end(cont), val);
    }
}

template &lt;typename Container, typename Value&gt;
auto contains(Container&amp;&amp; c, Value&amp;&amp; v) {
    return std::end(c) != find(c, std::forward&lt;Value&gt;(v));
}

int main() {
    std::map&lt;int, int&gt; map;
    std::vector&lt;int&gt; vector;

    find(map, 5);
    contains(vector, 5);
}