成员检测代码说明

时间:2012-12-27 22:01:33

标签: c++

它不是整个概念,而是用于确定某个类是否具有n数据成员的方法之一。这是完整的代码;普通使用SFINAE进行成员检测。

template <typename T>
struct has_X {
    struct Fallback { int X; };
    struct Derived : T, Fallback {};

    template <typename U, U> struct S;

    template <typename C> static char (&f(S<int Fallback::*, &C::X> *))[1];
    template <typename C> static char (&f(...))[2];

    public:
        const static bool value = sizeof(f<Derived>(0)) == 2;
};

Derived继承FallbackT的部分让我感到困惑,因为当我们执行f的重载时,&C::X为{{1} }。但是,不应该选择此重载,因为它不会&Derived::X保证Derived,因为它继承自具有该数据成员的X

也许我忽视了一些事情。然而,这段代码已经显示并教会了我从未知道的事情,所以也许 就是这样。我期望的是总是选择那个重载(而不是Fallback的那个),因为...应该总是Derived,因为它继承自X。但这种情况并非如此。有人可以解释一下原因吗?

1 个答案:

答案 0 :(得分:4)

Fallback有一个名为X的数据成员,但如果T还有一个名为X的成员,则Derived会有两个,其中案例Derived::X无法明确表达。因此,如果T没有X,则使用第一个重载,如果T具有X,则使用第二个更通用的版本。这就是为什么你可以根据返回类型的大小来区分这些情况。