Можно ли убрать или добавить объявление метода, в зависимости от типа шаблона класса?

Можно ли убрать или добавить объявление метода, в зависимости от типа шаблона класса? Я знаю что возможно выбрать перегрузку таким путем, но можно ли вообще убрать метод, который не подходит для данного типа шаблона? С помощью концептов или sfinae. Хотелось бы не специализировать для этого весь класс


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

Автор решения: HolyBlackCat

Легко, просто навешиваете requires:

template <bool X>
struct A
{
    void foo() requires X {/*...*/}
};

До C++20 нужно извращаться, потому что для нормальной работы SFINAE сама функция должна быть шаблоном, и условие должно зависеть от ее шаблонного параметра:

template <bool X>
struct A
{
    template <bool Y = X, std::enable_if_t<Y, std::nullptr_t> = nullptr>
    void foo() {/*...*/}
};

Еще вариант до С++20: как предложил @Mister_Jesus, кладете функции в родителя, и наследуетесь только если условие истинно. Например так:

template <bool X> struct B {/*условные функции тут*/};
template <> struct B<false> {};

template <bool X>
struct A : B<X> {};

Если в этих функциях нужно использовать this, то добавляете шаблонный параметр с собственным типом (CRTP: struct A : B<A, X>), а потом в родителе static_cast-уете this в указатель на потомка.

→ Ссылка