用于导入基本模板的所有名称的 C++ 宏 class
c++ macro to import all names of base template class
从模板库 class 派生 class 时,必须使用语法 this->member
或 using Base::member
来访问基地class。如果基础 class 是通用模板参数并且确定存在某些成员,则会发生同样的情况。
是否可以编写一个宏 "import" 我知道(或假设)存在的基 class 的所有成员?
简单示例:
struct A {
int x = 0;
};
struct B {
int x = 0;
int y = 1;
};
template <class T>
struct C {
int x = 0;
T z = 0;
};
template <class BaseClass>
struct Derived : BaseClass {
using BaseClass::x;
void setx1() { x = 1; }
};
template <class T>
struct Derived_from_C : C<T> {
using C<T>::x;
void setx1() { x = 1; }
};
int main()
{
Derived<A> a;
a.setx1();
Derived<B> b;
b.setx1();
Derived_from_C<double> c;
c.setx1();
return 0;
}
在定义 struct Derived
时,我假设模板参数 BaseClass
包含一个成员 x
,但要在成员 setx1
中使用它,我必须手动声明一个using
。 Derived_from _C
也是如此,其中基础 class 是模板 class。但是,如果基础 class 包含许多我想使用的成员,则为每个成员添加一个 using
会变得乏味且容易出错。
是否可以编写一个半自动执行此操作的宏?像
#define USING(class, __VA_ARGS__)
这样
USING(BaseClass, x, y, z)
扩展到
using BaseClass::x;
using BaseClass::y;
using BaseClass::z;
基于Marvin's solution to the question Is it possible to iterate over arguments in variadic macros这里有一个解决方案
#define FE_1(CLASS, X) using CLASS::X
#define FE_2(CLASS, X, ...) using CLASS::X;FE_1(CLASS, __VA_ARGS__)
#define FE_3(CLASS, X, ...) using CLASS::X;FE_2(CLASS, __VA_ARGS__)
#define FE_4(CLASS, X, ...) using CLASS::X;FE_3(CLASS, __VA_ARGS__)
#define FE_5(CLASS, X, ...) using CLASS::X;FE_4(CLASS, __VA_ARGS__)
#define FE_6(CLASS, X, ...) using CLASS::X;FE_5(CLASS, __VA_ARGS__)
#define FE_7(CLASS, X, ...) using CLASS::X;FE_6(CLASS, __VA_ARGS__)
#define FE_8(CLASS, X, ...) using CLASS::X;FE_7(CLASS, __VA_ARGS__)
#define FE_9(CLASS, X, ...) using CLASS::X;FE_8(CLASS, __VA_ARGS__)
#define FE_10(CLASS, X, ...) using CLASS::X;FE_9(CLASS, __VA_ARGS__)
#define FE_11(CLASS, X, ...) using CLASS::X;FE_10(CLASS, __VA_ARGS__)
#define FE_12(CLASS, X, ...) using CLASS::X;FE_11(CLASS, __VA_ARGS__)
//... repeat as needed
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,NAME,...) NAME
#define FOR_EACH_USING(class,...) \
GET_MACRO(__VA_ARGS__,FE_12,FE_11,FE_10,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,)(class,__VA_ARGS__)
从模板库 class 派生 class 时,必须使用语法 this->member
或 using Base::member
来访问基地class。如果基础 class 是通用模板参数并且确定存在某些成员,则会发生同样的情况。
是否可以编写一个宏 "import" 我知道(或假设)存在的基 class 的所有成员?
简单示例:
struct A {
int x = 0;
};
struct B {
int x = 0;
int y = 1;
};
template <class T>
struct C {
int x = 0;
T z = 0;
};
template <class BaseClass>
struct Derived : BaseClass {
using BaseClass::x;
void setx1() { x = 1; }
};
template <class T>
struct Derived_from_C : C<T> {
using C<T>::x;
void setx1() { x = 1; }
};
int main()
{
Derived<A> a;
a.setx1();
Derived<B> b;
b.setx1();
Derived_from_C<double> c;
c.setx1();
return 0;
}
在定义 struct Derived
时,我假设模板参数 BaseClass
包含一个成员 x
,但要在成员 setx1
中使用它,我必须手动声明一个using
。 Derived_from _C
也是如此,其中基础 class 是模板 class。但是,如果基础 class 包含许多我想使用的成员,则为每个成员添加一个 using
会变得乏味且容易出错。
是否可以编写一个半自动执行此操作的宏?像
#define USING(class, __VA_ARGS__)
这样
USING(BaseClass, x, y, z)
扩展到
using BaseClass::x;
using BaseClass::y;
using BaseClass::z;
基于Marvin's solution to the question Is it possible to iterate over arguments in variadic macros这里有一个解决方案
#define FE_1(CLASS, X) using CLASS::X
#define FE_2(CLASS, X, ...) using CLASS::X;FE_1(CLASS, __VA_ARGS__)
#define FE_3(CLASS, X, ...) using CLASS::X;FE_2(CLASS, __VA_ARGS__)
#define FE_4(CLASS, X, ...) using CLASS::X;FE_3(CLASS, __VA_ARGS__)
#define FE_5(CLASS, X, ...) using CLASS::X;FE_4(CLASS, __VA_ARGS__)
#define FE_6(CLASS, X, ...) using CLASS::X;FE_5(CLASS, __VA_ARGS__)
#define FE_7(CLASS, X, ...) using CLASS::X;FE_6(CLASS, __VA_ARGS__)
#define FE_8(CLASS, X, ...) using CLASS::X;FE_7(CLASS, __VA_ARGS__)
#define FE_9(CLASS, X, ...) using CLASS::X;FE_8(CLASS, __VA_ARGS__)
#define FE_10(CLASS, X, ...) using CLASS::X;FE_9(CLASS, __VA_ARGS__)
#define FE_11(CLASS, X, ...) using CLASS::X;FE_10(CLASS, __VA_ARGS__)
#define FE_12(CLASS, X, ...) using CLASS::X;FE_11(CLASS, __VA_ARGS__)
//... repeat as needed
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,NAME,...) NAME
#define FOR_EACH_USING(class,...) \
GET_MACRO(__VA_ARGS__,FE_12,FE_11,FE_10,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,)(class,__VA_ARGS__)