SFINAE C++ 方法检查

SFINAE C++ method check

我正试图全神贯注于 SFINAE。 我们用它来检查 class 是否有一个名为 "Passengers".

的方法

结合一些在线示例,我们构建了以下模板classes.

#ifndef TYPECHECK
#define TYPECHECK

#include "../Engine/carriage.h"

namespace TSS{

template<typename T>
class has_passengers{
private:
    typedef char one;
    typedef struct{char a[2];} two;

    template<typename C> static one test( decltype(&C::Passengers) );
    template<typename C> static two test(...);
public:
    static bool const value = sizeof(test<T>(0)) == sizeof(one);
};

template<typename T>
struct CarriageTypeCheck{
    static_assert(has_passengers<T>::value, "Train initialized with illegal carriage");
};

}


#endif // TYPECHECK

我知道如何选择两种测试方法中的任何一种,但我不明白的是为什么 test<T> 在以下行中用 0 初始化:

    static bool const value = sizeof(test<T>(0)) == sizeof(one);

我看不出 0 对于检查工作有多重要。 另一件事 - 为什么使用 decltype?

第一个重载函数(可能)将指向 class 方法的指针作为参数。由于 C++ 继承自 C,值 0 可转换为 NULL 指针,或 nullptr。所以,如果 SFINAE 没有踢出第一个重载函数,test<T>(0) 成为一个有效的函数调用,它的 sizeof 等于 sizeof(one)。否则这将解析为第二个重载函数调用。

以及关于为什么使用 decltype 的简短回答:否则它将不是有效的 C++。在函数声明中,函数的参数必须是类型,指定函数参数的类型。 &C::Passengers 不是类型(在其预期用途的上下文中),因此这不是有效的 C++。 decltype() of that automatically gets the type of its argument, making it valid C++.

I can not see how the 0 is important for the check to work.

因为 0 可以用作两种情况的参数(即两个重载的 test);对于成员指针(视为空指针)和可变参数 ....

Another thing - why is decltype used?

decltype用于描述成员指针的类型(即&C::Passengers)作为test的参数。