Подтвердить что ты не робот

С++ - Как ввести перегрузку из вариационного числа оснований.

Производный класс скрывает имя набора перегрузки из базового класса, если производный класс имеет одно и то же имя, но мы всегда можем ввести, что перегрузка установлена ​​с использованием-объявления:

template <class BASE>
class A : public BASE
{
public:
  using BASE::some_method;
  void some_method();
}

Но что, если я введу все наборы перегрузок из вариационных базовых классов? Смогу ли я написать что-то вроде этого?

template <class... BASES>
class A : public BASES...
{
public:
  using BASES::some_method...;
  void some_method();
}

Я рассмотрел использование вспомогательного класса, например:

template <class... BASES>
struct helper;

template <>
struct helper<> {};

template <class OnlyBase>
struct helper<OnlyBase> : OnlyBase
{
  using OnlyBase::some_method;
};

template <class Base1, class... OtherBases>
struct helper<Base1, OtherBases> : public Base1, public helper<OtherBases...>
{
  using Base1::some_method;
  using helper<OtherBases...>::some_method;
};

И это действительно работает. Но для этого требуется много ввода (конечно, я могу использовать макрос, но, когда это возможно, я стараюсь использовать функцию компиляции С++), и когда я хочу ввести больше методов, я должен многое изменить в этом фрагменте кода.

Идеальный ответ был бы простым синтаксисом, но если его нет, я перейду со вспомогательным классом.

4b9b3361

Ответ 1

Вот трюк, как уменьшить почерк:

// U<X,Y> is a binary operation on two classes
template<template<class,class>class U, class... Xs> struct foldr;
template<template<class,class>class U, class X> struct foldr<U,X> : X {};
template<template<class,class>class U, class X, class... Xs> struct foldr<U,X,Xs...> : U<X, foldr<U,Xs...>> {};

// our operation inherits from both classes and declares using the member f of them    
template<class X, class Y> struct using_f : X,Y { using X::f; using Y::f; };

struct A { void f(int) {} };
struct B { void f(char) {} };
struct C { void f(long) {} };

struct D : foldr<using_f, A, B, C> {};


int main() {
    D d;
    d.f(1);
    d.f('1');
    d.f(1L);
    return 0;
}

Итак, мы должны написать foldr один раз, а затем написать простые ad-hoc операции - using_f, using_g, using_f_g

Может быть, есть способ дальнейшего упрощения. Позвольте мне немного подумать...