繁体   English   中英

通过类型获取具有递归继承的可变参数模板的阴影成员

[英]Get shadowed members of variadic template with recursive inheritance by type

我有类似以下内容:

template <typename T>
class A {
public:
    typedef T Type;
};

template <typename...> class B;

template <typename TFirst, typename... TRest>
class B<TFirst, TRest...> : public B<TRest...> {
public:
    typedef typename TFirst::Type Type;

    TFirst a;

    virtual void func(TFirst a, Type t) = 0;
};

template <>
class B<> {};

struct X {};
struct Y {};

class ASub1 : public A<X> {};
class ASub2 : public A<Y> {};

class BSub : public B<ASub1, ASub2> {
public:
    // Implement all pure virtual methods
    // void func(ASub1 a1, Type t) override {}
    // void func(ASub2 a2, Type t) override {}
};

现在我有两个问题:

  1. 我将如何在BSub实现所有纯虚拟方法? 我以某种方式需要访问所有ASubX的模板参数(类型)。

  2. 是否可以通过传递ASubX来访问所有成员a 我的意思是这样get<ASub1>(b_sub)如果b_sub是实例BSub

我希望使用C ++ 14解决方案。

对于(1),您可以编写

class BSub : public B<ASub1, ASub2> {
public:
    void func (ASub1, typename ASub1::Type) override {}
    void func (ASub2, typename ASub2::Type) override {}
};

或者,记住ASub1::TypeXASub2::TypeY

class BSub : public B<ASub1, ASub2> {
public:
    void func (ASub1, X) override {}
    void func (ASub2, Y) override {}
};

对于(2),根据WF的建议,您可以使用

b_sub.B<ASub1, ASub2>::a

访问ASub1组件,并

b_sub.B<ASub2>::a

访问ASub2一个。

以下是完整的工作(简化)示例

#include <iostream>
#include <type_traits>

template <typename T>
struct A
 { using Type = T; };

template <typename...>
struct B;

template <typename TFirst, typename ... TRest>
struct B<TFirst, TRest...> : public B<TRest...>
 {
    using Type = typename TFirst::Type;

    TFirst a;

    virtual void func (TFirst a, Type t) = 0;
 };

template <>
struct B<> {};

struct X {};
struct Y {};

struct ASub1 : public A<X> {};
struct ASub2 : public A<Y> {};

struct BSub : public B<ASub1, ASub2>
 {
   void func (ASub1, X) override { std::cout << 1 << std::endl; }
   void func (ASub2, Y) override { std::cout << 2 << std::endl; }
 };

int main()
 {
   BSub bs;

   bs.func(ASub1{}, X{});
   bs.func(ASub2{}, Y{});

   using T1 = decltype(bs.B<ASub1, ASub2>::a);
   using T2 = decltype(bs.B<ASub2>::a);

   static_assert(std::is_same<T1, ASub1>{}, "!");
   static_assert(std::is_same<T2, ASub2>{}, "!");
 }

std::get for std::tuple实现的启发,我想出了以下解决方案。

谢谢你的帮助。

#include <cstdio>

template <typename T>
class A {
public:
    using Type = T;
};

template <typename...> class B;

template <typename TFirst, typename... TRest>
class B<TFirst, TRest...> : public B<TRest...> {
public:
    using AType = typename TFirst::Type;
    using Type = B<TFirst, TRest...>;

    TFirst a;

    virtual void func(TFirst a, AType t) {}
};

template <>
class B<> {};

struct X {};
struct Y {};

class ASub1 : public A<X> { public: int value = 10; };
class ASub2 : public A<Y> { public: int value = 20; };

class BSub : public B<ASub1, ASub2> {
public:
    // Implement all pure virtual methods
    void func(ASub1 a1, typename ASub1::Type t) {}
    void func(ASub2 a2, typename ASub2::Type t) {}
};

template <typename TA, typename TB> class BElement;

template <typename TA, typename TAFirst, typename... TARest>
class BElement<TA, B<TAFirst, TARest...>> : public BElement<TA, B<TARest...>> {
public:
};

template <typename TA, typename... TARest>
class BElement<TA, B<TA, TARest...>> {
public:
    using AType = TA;
    using BType = B<TA, TARest...>;
};

template <typename TA, typename... TAs>
TA& get(B<TAs...> & b) {
    using BType = typename BElement<TA, B<TAs...>>::BType;
    return static_cast<BType &>(b).a;
}

template <typename TA, typename TB>
TA& get(TB b) {
    return get<TA>(static_cast<typename TB::Type &>(b));
}

int main() {
  BSub bsub;
  printf("%d\n", get<ASub1>(bsub).value);
  printf("%d\n", get<ASub2>(bsub).value);

  return 0;
}

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM