Using SFINAE partial specialization without touching the main template

I am trying to specialize a structure template for several types at once SFINAE. I know that something like the following works:

#include <iostream>

template <typename T, typename Enable = void>
struct S {
    void operator()() {
        std::cout << "Instantiated generic case" << std::endl;
    }
};

template<typename T>
using enabled_type = typename std::enable_if<
                         std::is_same<T, int>::value ||
                         std::is_same<T, float>::value
                     >::type;

template <typename T>
struct S<T, enabled_type<T>> {
    void operator()() {
        std::cout << "Instantiated int/float case" << std::endl;
    }
};

int main() {
    S<float>()();
    return 0;
}

My problem is that I cannot change the main S struct template to add typename Enable = voidas it is part of the outer header of the library. Therefore, the main template should look like this:

template <typename T>
struct S {
    void operator()() {
        std::cout << "Instantiated generic case" << std::endl;
    }
};

Can SFINAE be used to specialize this template?

: , S , S . , , , SFINAE , ( , ).

+4
2

: , , . , void enable_if, . , :

template <class T>
struct foo {};

template <class T>
struct S<foo<T>> {};

. , , , , .

std::hash , . , , hash , .

: std:: hash . - , , . ++ , , OP , . , , .

hash , , , . , -, . , . , , :

template <class T, class = void>
struct S {};

template <>
struct S<double> {};

.

+2

, ?

struct S_int_or_float {
    void operator()() {
        std::cout << "Instantiated int/float case" << std::endl;
    }
};

template<> struct S<int>: S_int_or_float {};
template<> struct S<float>: S_int_or_float {};

Edit: , ... , ... , :

struct ParentS { /* some implementation */ }; 

template <class First, class Second>
struct S<First, Second, enable_if_t<trait_for_first_and_second<First, Second>::value, first_accepted_type_of_third_parameter> >: ParentS { };

template <class First, class Second>
struct S<First, Second, enable_if_t<trait_for_first_and_second<First, Second>::value, second_accepted_type_of_third_parameter> >: ParentS { };

// ...

, SFINAE, ...

+2

Source: https://habr.com/ru/post/1650720/


All Articles