C ++ - 如何从可变基数引入过载集。 [英] C++ - How to introduce overload set from variadic number of bases.

查看:169
本文介绍了C ++ - 如何从可变基数引入过载集。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果派生类定义了相同的名称,派生类隐藏了来自基类的重载集合的名称,但我们总是可以使用using-declaration引入重载集合:

 模板< class BASE> 
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();
}



我考虑过使用一个辅助类:

 模板< class ... BASES> 
struct helper;

模板<>
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 ...>
{
使用Base1 :: some_method;
使用辅助程序< OtherBases ...> :: some_method;
};

它可以工作。但是它需要大量的输入(当然我可以使用宏,但我尽量使用c ++的编译时功能,尽可能),当我想介绍更多的方法,我必须改变很多的那段代码。 p>

一个完美的答案将是一个简单的语法,但如果没有,我将与帮助类。

解决方案

这里是一个如何减少手写的技巧:

  // U< X,Y& ;是对两个类的二元操作
template< template< class,class> class U,class ... Xs> struct foldr;
template< template< class,class> class U,class X>结构折叠< U,X> : X {};
template< template< class,class> class U,class X,class ... Xs> struct foldr< U,X,Xs ...> :U
//我们的操作从两个类继承,并使用它们的成员f声明
template< class X,class Y> struct using_f:X,Y {using X :: f;使用Y :: f; };

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

struct D:foldr< use_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



也许有办法进一步简化。让我想一点...


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.

解决方案

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...

这篇关于C ++ - 如何从可变基数引入过载集。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆