检查类型是否直接从“如果……启用时”上下文中的另一类型派生(是其子代)

问题描述 投票:4回答:1

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++ inheritance sfinae enable-if subtype
1个回答
0
投票

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函数来解决

© www.soinside.com 2019 - 2024. All rights reserved.