简体   繁体   English

如何调用所有可变继承类的函数?

[英]How can I call a function of all variadically inherited classes?

I'd be grateful to any template gurus out there for some help on this one.我会感谢任何模板专家在此方面提供帮助。 I'm using CRTP for a mixin class and would like to be able to pass arguments to a function of the derived class and have it call the inherited functions of all mixins and forward the appropriate number of arguments.我正在将 CRTP 用于 mixin 类,并希望能够将参数传递给派生类的函数,并让它调用所有 mixin 的继承函数并转发适当数量的参数。 Eg:例如:

template<Host> struct Mixin1 { void Initialize(int, double); };
template<Host> struct Mixin2 { void Initialize(); };
template<Host> struct Mixin3 { void Initialize(double); };

template <template<class> class... Components>
struct Entity : public Components<Entity<Components...>>...
{
    template<template<class> class ...Types, template<template<typename>typename...> class T, class... Args>
    void Initialize(const T<Types...>&, Args&&... args) {
      (Types<Entity<Types>>::Initialize(forward<Types>(args)),...);
    }
}

And use like:并使用如下:

entity.Initialize(42,42.0,42.0);

Is it possible to pass the appropriate number of arguments to each?是否可以将适当数量的参数传递给每个参数? The code above of course doesn't work but my idea was to try the method of instantiating an empty template with the types of each of the arguments (ie Variad<int, double> v1; Variad<> v2; Variad<double> v3; ) and pass a variad containing all those into the function along with the arguments but I can't seem to figure out how to split the arguments correctly.上面的代码当然不起作用,但我的想法是尝试使用每个参数的类型实例化一个空模板的方法(即Variad<int, double> v1; Variad<> v2; Variad<double> v3; ) 并将包含所有这些的变量与参数一起传递到函数中,但我似乎无法弄清楚如何正确拆分参数。

Is it possible to pass the appropriate number of arguments to each?是否可以将适当数量的参数传递给每个参数?

Not in a simple way, as far I can understand.不是以一种简单的方式,据我所知。

Surely it's possible, counting argument of every method and using recursion (also recursive variadic lambdas) and SFINAE.当然有可能,计算每个方法的参数并使用递归(也是递归可变参数 lambdas)和 SFINAE。

I've developed the following example just because I love template metaprogramming;我开发了以下示例只是因为我喜欢模板元编程; but I'm the first to say that it's a delirious nightmare.但我是第一个说这是一场神志不清的噩梦的人。

#include <utility>
#include <iostream>
#include <type_traits>

template <typename R, typename T, typename ... As>
constexpr std::size_t numArgs (R(T::*)(As...))
 { return sizeof...(As); }

template <typename>
struct Mixin1
 {
   void Initialize (int i, double d)
    { std::cout << "I1: " << i << ", " << d << std::endl; }
 };

template <typename>
struct Mixin2
 {
   void Initialize ()
    { std::cout << "I2:" << std::endl; }
 };

template <typename>
struct Mixin3
 {
   void Initialize (double d)
    { std::cout << "I3: " << d << std::endl; }
 };

template <template <typename> class ... Cs>
struct Entity : public Cs<Entity<Cs...>>...
 {
   template <std::size_t Pos, typename ... Ts,
             typename F, std::size_t I0, std::size_t ... Is,
             typename ... As>
   std::enable_if_t<(Pos == I0)>
      Ih2 (F const & f, std::index_sequence<I0, Is...> const &,
           As && ... as)
    { 
      f(); // exec an Initialize();

      Ih1<Ts...>(std::index_sequence<Is...>{}, std::forward<As>(as)...);
    }

   template <std::size_t Pos, typename ... Ts,
             typename F, std::size_t I0, std::size_t ... Is,
             typename A0, typename ... As>
   std::enable_if_t<(Pos < I0)>
      Ih2 (F const & f, std::index_sequence<I0, Is...> const & is,
           A0 && a0, As && ... as)
    { Ih2<Pos+1u, Ts...>
       ([&a0, &f](auto && ... as2) { f(std::forward<A0>(a0),
                                     std::forward<decltype(as2)>(as2)...); },
        is, std::forward<As>(as)...); }

   template <int = 0>
   void Ih1 (std::index_sequence<> const &)
    { }

   template <typename T0, typename ... Ts,
             std::size_t ... Is, typename ... As>
   void Ih1 (std::index_sequence<Is...> const & is, As && ... as)
    { Ih2<0u, Ts...>
       ([this](auto && ... as2)
           { T0::Initialize(std::forward<decltype(as2)>(as2)...); },
        is, std::forward<As>(as)...); }

   template <typename ... As>
   void Initialize (As && ... args)
    { Ih1<Cs<Entity<Cs...>>...>
       (std::index_sequence<numArgs(&Cs<Entity<Cs...>>::Initialize)...>{},
        std::forward<As>(args)...); }
 };

int main ()
 {
   Entity<Mixin1, Mixin2, Mixin3> entity;

   entity.Initialize(1, 2.0, 3.0);
 }

As said in a comment, this solution doesn't works in case of overloading, or template, for Initialize() in the single Components .正如评论中所说,此解决方案在重载或模板的情况下不适用于单个Components中的Initialize()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将成员函数添加到需要它的继承类而不影响其他同级类,同时保持多态性? - How can I add a member function to the inherited class that needs it without affecting the other sibling classes all while maintaining Polymorphism? 如何仅通过调用基类的相同方法来调用继承类的方法? - How can I call methods of inherited classes just by calling the same method of base class? 我可以在参数包扩展中调用所有基类的函数吗? - Can I call a function on ALL base classes in a parameter pack expansion? 如何在同一个数组中将多个继承的类放在一起? - How can I have several inherited classes together in the same array? 如何从上面的 class 调用 function? class 未被继承 - how do I call the function from the upper class? the class is not inherited 构造函数调用继承的类 - Constructor call in inherited classes 如何通过虚拟function运行所有继承的function? - How to run all inherited function by there virtual function? 您可以查询所有继承类的相同命名方法吗? - Can you query same named methods of all inherited classes? 如何从继承的类中调用函数? - How to call function from inherited class? 如何为从一个继承而来的所有创建的对象调用虚函数? C++ - How to call virtual function for all created objects which are inherited from the one? C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM