How to make a template only for classes that have a specific function?

What I mean is kind of like how the for each loop only works with functions that have a begin and end function.
std::enable_if
This metafunction is a convenient way to leverage SFINAE to conditionally remove functions from overload resolution based on type traits and to provide separate function overloads and specializations for different type traits.
http://en.cppreference.com/w/cpp/types/enable_if


For instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <type_traits>
#include <iterator>

namespace detail
{
    using std::begin ;
    template < typename T > struct has_begin
    {
        template < typename U > static std::true_type test( U&, decltype( begin( std::declval<U&>() ) )* ) ;
        template < typename U > static std::false_type test( U&, ... ) ;

        using type = decltype( test( std::declval<T&>(), nullptr ) ) ;
        static constexpr bool value = type::value ;
    };
}

template < typename T > typename std::enable_if< detail::has_begin<T>::value, bool >::type foo( const T& seq )
{
    std::cout << "has begin\n" ;
    for( const auto& value : seq ) { /* whatever */ }
    return true ;
}

int main()
{
    const int a[] = { 23, 56, 77, 82, 17 } ;
    foo(a) ; // fine: has begin

    foo(std::cout) ; // ***error: o matching function for call to 'foo'
                     // note:candidate template ignored: disabled by 'enable_if'
}
Topic archived. No new replies allowed.