SFINAE vs concepts deliver different results for enum type
05:18 16 Dec 2025

Only for academic reasons I try out SFINAE vs. concepts and wrote my own traits. I know there is `std::is_integral` and a lot of other stuff.

I use decltype( ptr+ T{}){}; to check if it is an integer type. With SFINAE it reports "false" and with concepts it reports "true".

Full code example:

#include 

// SFINAE
template < typename T >
struct my_is_integral
{
    template < typename C >
    static constexpr std::true_type check( C,  decltype( std::declval()+ C{})=nullptr)
    {
        return {};
    }

    template < typename >
        static constexpr std::false_type check( ... ) { return {}; }

    using type = decltype( check( 0 ));
    static constexpr bool value = type::value;
};

template < typename T>
auto sfinaeIntegral(T) -> std::enable_if_t< my_is_integral::value, void >
{
    std::cout << "yes" << std::endl;
}
template < typename T>
auto sfinaeIntegral(T) -> std::enable_if_t< !my_is_integral::value, void >
{
    std::cout << "no" << std::endl;
}

// ------------- concepts

template < typename T >
concept is_integer = requires( T, int* ptr )
{
    decltype( ptr+ T{}){};
};

class C{};
enum E{};

int main()
{
    sfinaeIntegral( 1 );
    sfinaeIntegral( 'a' );
    sfinaeIntegral( 1.1 );
    sfinaeIntegral( C{} );
    sfinaeIntegral( E{} );

    std::cout << is_integer << std::endl;
    std::cout << is_integer << std::endl;
    std::cout << is_integer << std::endl;
    std::cout << is_integer << std::endl;
}

live

c++ sfinae c++-concepts