[英]Get shadowed members of variadic template with recursive inheritance by type
I have something like the following: 我有类似以下内容:
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 {}
};
Now I have two questions: 现在我有两个问题:
How would I be able to implement all pure virtual methods in BSub
? 我将如何在
BSub
实现所有纯虚拟方法? I somehow need to access the template arguments (types) of all ASubX
. 我以某种方式需要访问所有
ASubX
的模板参数(类型)。
Is there a way to access all the members a
by passing the ASubX
? 是否可以通过传递
ASubX
来访问所有成员a
? I mean something like get<ASub1>(b_sub)
if b_sub
were an instance of BSub
. 我的意思是这样
get<ASub1>(b_sub)
如果b_sub
是实例BSub
。
I would prefer a solution with C++14. 我希望使用C ++ 14解决方案。
For (1), you can write 对于(1),您可以编写
class BSub : public B<ASub1, ASub2> {
public:
void func (ASub1, typename ASub1::Type) override {}
void func (ASub2, typename ASub2::Type) override {}
};
or, remebering that ASub1::Type
is X
and ASub2::Type
is Y
, 或者,记住
ASub1::Type
为X
而ASub2::Type
为Y
,
class BSub : public B<ASub1, ASub2> {
public:
void func (ASub1, X) override {}
void func (ASub2, Y) override {}
};
For (2), as suggested by WF, you can use 对于(2),根据WF的建议,您可以使用
b_sub.B<ASub1, ASub2>::a
to access the ASub1
component and 访问
ASub1
组件,并
b_sub.B<ASub2>::a
to access the ASub2
one. 访问
ASub2
一个。
The following is a full working (simplified) example 以下是完整的工作(简化)示例
#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>{}, "!");
}
Inspired by an implementation of std::get
for std::tuple
I came up with following solution. 受
std::get
for std::tuple
实现的启发,我想出了以下解决方案。
Thanks for your help. 谢谢你的帮助。
#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.