C++ 用于确定一个类是否派生自另一个类的代码解释

C++ 用于确定一个类是否派生自另一个类的代码解释,c++,c++11,C++,C++11,目的是检测模板类型参数D是否派生自模板类型参数B。下面的代码在类IsDerivedHelper中具有私有静态方法。问题是Helper类中的静态方法是如何工作的?它没有定义 #include<iostream> #include<type_traits> using namespace std; class IOne { private: public: IOne() = delete; virtual void print() = 0; }; cla

目的是检测模板类型参数
D
是否派生自模板类型参数
B
。下面的代码在类
IsDerivedHelper
中具有私有静态方法。问题是
Helper类中的静态方法是如何工作的?
它没有定义

#include<iostream>
#include<type_traits>

using namespace std;

class IOne
{
private:
public:
    IOne() = delete;
    virtual void print() = 0;
};

class One :public IOne
{
public:
    One() = default;
    virtual void print()
    {
        cout << "printed from class One" << endl;
    }
};

class Two
{

};

template<typename D, typename B> class IsDerivedHelper
{
    class No{};
    class Yes { No no[3]; };
    static Yes Test(B*);
    static No Test(...);
public:
    enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
};

void main()
{
    auto v = IsDerivedHelper<One, IOne>::Is;    // Value is 1
    // auto v = IsDerivedHelper<Two, IOne>::Is; // Value is 0
    if (v)
    {
        cout << "Is derived" << endl;
    }
    else 
    {
        cout << "Not a derived." << endl;
    }
}
#包括
#包括
使用名称空间std;
IOne类
{
私人:
公众:
IOne()=删除;
虚空打印()=0;
};
第一类:公共离子
{
公众:
一个()=默认值;
虚拟空打印()
{

这在编译时确实有效,核心是决定使用哪个
isderivedheloper::Test
重载

这个电话在这里

sizeof(Test(static_cast<D*>(0)))
如果传递的参数是从B派生的,则使用第一个参数。 第二个参数用于任何其他情况。
..
表示“任何参数”

静态方法永远不会被调用,一切都是在编译时计算的


这是一套巧妙的技巧

这本书评有一个完整的解释。去读吧。它很有启发性,尽管年代久远,但千万不要使用它。避免一次问多个不同的问题。参见。仅供参考,C++11提供了:“检查一个类型是否派生自另一个类型”,所以实际上根本不需要
IsDerivedHelper
auto v=std::is_base_of::value;
auto v=std::is_base of::value;
你知道为什么
否[3]
用于强制两个重载的返回大小不同。一个返回a No,另一个返回3 nowy 3,2也可以与2一起使用。您必须询问原始作者为什么选择3
   static Yes Test(B*);
    static No Test(...);