Условное переопредлеение метода

Возможно ли, в рамках С++17|20 компактно записать условную реализацию метода базового класса? Не компилируемый пример:

struct S1
{
    virtual int func1() { return 10; }
};
struct S2
{
    virtual int func2() { return 20; }
};

template<typename Base>
struct Wrap : Base
{
    static constexpr bool has_func1 = std::is_same< Base, S1 >::value;
    static constexpr bool has_func2 = std::is_same< Base, S2 >::value;

    requires has_func1 // Не работает, поскольку func1 - не шаблонная функция
    int  func1() override { return Base::func1() +1; }

    std::enable_if_t<has_func2, int>  // дает ошибку компиляции, если has_func2==false
    func2() override { return Base::func2() +1; }
};

Wrap<S1> instance;
Wrap<S2> instance;

Понимаю, что есть с++11 - решение со специализацией класса, в зависимости от флага:

template<typename Base, bool has_func1 = std::is_same< Base, S1 >::value >
struct SpecialWrap;

template<typename Base>
struct SpecialWrap<Base, true> : Base
{
    int  func1() override { return Base::func1() +1; }
};
template<typename Base>
struct SpecialWrap<Base, false> : Base
{};

template<typename Base>
struct Wrap : SpecialWrap< Base >
{
   ...
};

Но получается уж очень многословно, особенно, если нужно учесть несколько условий.


Ответы (1 шт):

Автор решения: AR Hovsepyan

Я уже написал в комментарии свой взгляд на это и полностью поддерживаю мнение isnullxbh в комментариях. Но если нужно, то я бы сделал что то типа:

struct B {
    virtual int func() = 0;    
};
struct S1 : B
{   
    virtual int func() override { return func1(); }
private:
    int func1() { return 10; }
};
struct S2 : B
{    
    virtual int func() override { return func2(); }
private:
    int func2() { return 20; }
};

template<typename Base>
struct Wrap : Base{ };

Wrap<S1> w1; Wrap<S2> w2;
→ Ссылка