c ++, используя enable_if вместе с существующим классом шаблона? - PullRequest
1 голос
/ 30 марта 2020

У меня есть шаблон класса A, B, который нельзя изменить.

template<class T> 
struct A{static void F(){}};
template<int I>
struct B{};

Я хочу специализироваться A только тогда, когда T равно B<I> и 1<=I<=5.

Если A можно изменить, это будет выглядеть следующим образом:

template<class T,class = void>//added second param 
struct A{static void F(){}};
template<int I>
struct B{};

template<int I>
struct A< B<I>, std::enable_if_t<(1<=I&&I<=5)> >{static void F(){}};

int main(){
  A<B<0>>::F();//call origin ver
  A<B<1>>::F();//call specialized ver
  A<B<10>>::F();//call origin ver
}

Возможно ли это?

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Вы можете перенаправить специализацию в наследование от условной реализации

template<class T> 
struct A{
    static void F() { std::cout << "default\n"; }
};

template<int I>
struct B{};

struct tag{};

template<int I>
struct ABImpl {
    static void F() { std::cout << "specialized for " << I << '\n'; }
};

template<int I>
struct A<B<I>> : std::conditional_t<1 <= I && I <= 5, ABImpl<I>, A<tag>> {};

tag - это пустышка, которая просто используется для получения реализации по умолчанию без риска конфликта.

Пример в реальном времени

0 голосов
/ 30 марта 2020

Добавьте один слой косвенности.

template <class T>
struct SpecializedA {
    //... specialized implementation
};

template<class T,class = void>//added second param 
struct MyA_impl{
    using type = A<T>;
};

template<int I>
struct MyA_impl< B<I>, std::enable_if_t<(1<=I&&I<=5)> >{
    using type = SpecializedA<B<I>>;
};

template <typename T>
using MyA = typename MyA_impl<T>::type;

С этим мы получим

MyA<B<0>> == A<B<0>>  
MyA<B<1>> == SpecializedA<B<1>>  
MyA<int> == A<int>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...