C ++具有is_base_of<Base,Derived>
。但是,这也包括“祖父母”类型。
是否有办法获得is_base_of<Base,Derived>
功能?目的是在SFINAE上下文中将类型用作前哨“接口”标记,而不受可能添加或不添加到父类型的标记的影响。
即,以下输出应为“ true,false”。 (is_child_of<Parent,Child>
的输出为“ true,true”。)
is_base_of
C ++没有反射,子级的存储包含父级的存储,很难在一个子对象和另一个子对象之间画一条线。一些元编程必须是半球形的,模仿类似于Qt或MFC \ WFC的库]
#include <iostream>
#include <type_traits>
class A {};
class B : A {};
class C : B {};
int main()
{
std::cout << std::boolalpha;
std::cout << "a2b: " << std::is_child_of<A, B>::value << '\n';
std::cout << "a2c: " << std::is_child_of<A, C>::value << '\n';
}
很显然,这种简单的方法存在一个陷阱,如果没有使用宏定义类,那么我们不会出错,并且它只是静态的,
第一个问题可以通过声明创建一个“ trait”嵌套类来解决,该类基于传递给DECLARE_OBJECT的类名来获取名称。这将使PARENT_CLASS(Name)的结果唯一,例如
#include <iostream>
#include <type_traits>
#define DECLARE_CLASS(Name, ParentName) using Parent = ParentName;
#define PARENT_CLASS(Name) Name::Parent
class LibBase {
public:
DECLARE_CLASS(LibBase, void)
};
class A : public LibBase {
public:
DECLARE_CLASS(A, LibBase)
};
class B : public A {
public:
DECLARE_CLASS(B, A)
};
int main()
{
std::cout << std::boolalpha;
std::cout << std::is_same<PARENT_CLASS(B), A>::value << std::endl;
std::cout << std::is_same<PARENT_CLASS(B), LibBase>::value << std::endl;
}
第二个问题可以通过在宏定义内创建自己的RTTI函数来解决