C++ - How to introduce overload set from variadic number of bases.

空扰寡人 提交于 2019-12-11 11:56:51

问题


The derived class hides the name of an overload set from the base class if the derived class has the same name defined, but we can always introduce that overload set back with using-declaration:

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

But what if I introduce all overload sets from variadic base classes? Would I be able to write something like this?

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

I've considered using a helper class like:

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;
};

And it does work. But it requires a lot of typing (of course I can use macro but I try to use c++'s compile-time feature whenever possible), and when I want to introduce more methods, i have to change much in that piece of code.

A perfect answer would be a simple syntax, but if there's none, I will go with the helper class.


回答1:


Here is a trick how to reduce handwriting:

// 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;
}

So we should write foldr once, then write simple ad-hoc operations - using_f, using_g, using_f_g

Maybe there is a way to further simplifying. Let me think a bit...



来源:https://stackoverflow.com/questions/34418749/is-there-a-work-around-for-parameter-pack-expansion-in-using-declarations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!