用于确定类是否派生自另一个类的代码说明

时间:2017-11-16 17:41:31

标签: c++ c++11

目的是检测模板类型参数D是否来自模板类型参数B。以下代码在类IsDerivedHelper中具有私有静态方法。问题是How does the static method inside the Helper class works?它没有定义。

#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;
    }
}

提前致谢。

1 个答案:

答案 0 :(得分:1)

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

这次来电

sizeof(Test(static_cast<D*>(0)))

将返回选择了重载的返回值的sizeof。全部都在编译时。

两个重载是

   static Yes Test(B*);
    static No Test(...);

如果传递的参数是从B派生的,则使用第一个。 第二个用于任何其他情况。 ...表示'any args'

永远不会调用静态方法,所有内容都在编译时进行评估。

这是一套巧妙的技巧