Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 按类型获取具有递归继承的可变模板的阴影成员_C++_Templates_Recursion_C++14_Variadic Templates - Fatal编程技术网

C++ 按类型获取具有递归继承的可变模板的阴影成员

C++ 按类型获取具有递归继承的可变模板的阴影成员,c++,templates,recursion,c++14,variadic-templates,C++,Templates,Recursion,C++14,Variadic Templates,我有如下几点: 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

我有如下几点:

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 {}
};
模板
甲级{
公众:
T型;
};
模板B类;
模板
乙类:公共乙类{
公众:
typedef typename TFirst::Type Type;
第一阶段a;
虚空函数(t第一个a,类型t)=0;
};
模板
B类{};
结构X{};
结构Y{};
ASub1类:公共A{};
ASub2类:公共A{};
B类:公共B类{
公众:
//实现所有纯虚拟方法
//void func(ASub1 a1,类型t)重写{}
//void func(ASub2 a2,类型t)重写{}
};
现在我有两个问题:

  • 如何在
    BSub
    中实现所有纯虚拟方法?我需要访问所有
    ASubX
    的模板参数(类型)

  • 是否有方法通过传递
    ASubX
    来访问所有成员
    a
    ?我的意思是,如果
    b_sub
    b_sub
    的一个实例,则类似于
    get(b_sub)

  • 我更喜欢使用C++14的解决方案。

    对于(1),您可以编写

    class BSub : public B<ASub1, ASub2> {
    public:
        void func (ASub1, typename ASub1::Type) override {}
        void func (ASub2, typename ASub2::Type) override {}
    };
    
    对于(2),正如W.F.所建议的,您可以使用

    b_sub.B<ASub1, ASub2>::a
    
    访问
    ASub2
    one

    下面是一个完整的工作(简化)示例

    #包括
    #包括
    模板
    结构A
    {使用Type=T;};
    模板
    结构B;
    模板
    结构B:公共B
    {
    使用Type=typename TFirst::Type;
    第一阶段a;
    虚空函数(t第一个a,类型t)=0;
    };
    模板
    结构B{};
    结构X{};
    结构Y{};
    结构ASub1:公共A{};
    结构ASub2:公共A{};
    结构B sub:public B
    {
    
    void func(ASub1,X)重写{std::cout的灵感来自
    std::get
    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;
    }
    
    #包括
    模板
    甲级{
    公众:
    使用类型=T;
    };
    模板B类;
    模板
    乙类:公共乙类{
    公众:
    使用AType=typename TFirst::Type;
    使用类型=B;
    第一阶段a;
    虚void func(TFirst a,AType t){}
    };
    模板
    B类{};
    结构X{};
    结构Y{};
    类ASub1:public A{public:int value=10;};
    类ASub2:public A{public:int value=20;};
    B类:公共B类{
    公众:
    //实现所有纯虚拟方法
    void func(ASub1 a1,类型名ASub1::类型t){}
    void func(ASub2 a2,类型名ASub2::类型t){}
    };
    模板类标线;
    模板
    等级:公共安全带{
    公众:
    };
    模板
    班带{
    公众:
    使用AType=TA;
    使用BType=B;
    };
    模板
    TA&get(食宿){
    使用BType=typename BElement::BType;
    返回静态_cast(b.a);
    }
    模板
    TA&get(TB b){
    返回get(静态_cast(b));
    }
    int main(){
    BSub BSub;
    printf(“%d\n”,get(bsub).value);
    printf(“%d\n”,get(bsub).value);
    返回0;
    }
    
    至于2.
    b_sub.b::a
    应该可以做到这一点。请记住,您可以将多个
    ASubX
    传递给
    b
    ,编译器需要明确知道您指的是哪一个。。。
    b_sub.B<ASub2>::a
    
    #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>{}, "!");
     }
    
    #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;
    }