首页 > 解决方案 > 了解 std::is_base_of 的重新实现

问题描述

我在网上遇到了以下代码。它本质上是为了说明一种实现方式std::is_base_of(也许不精确)。

我添加了编号的注释,以将行与下面提出的特定问题相关联:

#include <type_traits>
#include <iostream>

class Q {};

class Z : public Q {};

template<typename D, typename B>
class IsDerivedFromHelper
{
    class No { };
    class Yes { No no[3]; };

    static Yes Test( B* );  // (1) (2)
    static No Test( ... );  // (1) (3)
public:
    enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) }; // (4)

};

template <class C, class P> 
bool IsDerivedFrom() {
    return IsDerivedFromHelper<C, P>::Is;
}

int main(int argc, char** argv) {
    std::cout << IsDerivedFrom<Z, Q>() << std::endl;

    return 0;
}

这里有很多事情我没有弄清楚。协助将不胜感激。

  1. 在我看来,定义了两个同名的IsDerivedFromHelper静态成员()?这怎么可能?Test

  2. 这两个类NoYes没有定义构造函数,这意味着它们只有默认的无参数构造函数。如果是这样,我们如何能够传递B*(或...)到Test()

  3. 我理解这...意味着可变参数。但是——在这种情况下是什么意思?

  4. Test同样,使用类型的参数进行实例化,D*其中的类型Test没有定义构造函数。这里发生了什么?

标签: c++templatesmetaprogramming

解决方案


  1. 在我看来 IsDerivedFromHelper 定义了两个同名的静态成员(Test)?这怎么可能?

那些同名的成员函数有不同的参数列表。这称为函数重载。

  1. No 和 Yes 类都没有定义构造函数,这意味着它们只有默认的无参数构造函数。如果是这样,我们如何将 B*(或 ...)传递给 Test()?

函数的返回类型对可以传递给它的参数没有影响。

  1. 我知道 ... 意味着可变参数。但是——在这种情况下是什么意思?

变幻莫测的论点。

  1. 同样,使用 D* 类型的参数实例化 Test,其中 Test 的类型没有定义构造函数。

一个函数被调用,而不是实例化。函数没有构造函数。

这里发生了什么?

调用成员函数Test。根据模板类型参数,调用可能会解析为任一重载。


推荐阅读