简体   繁体   中英

Explanation on Member Detection code

It's not the concept as a whole, but rather one of the methods it uses to determine if a class has an n data-member. Here is the full code; an ordinary use of SFINAE for member detection.

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

The part where Derived inherits from both Fallback and T confuses me because when we do the overload of f , &C::X is &Derived::X . But shouldn't this overload always be chosen because isn't Derived guaranteed to have X since it inherits from Fallback which has that data-member?

Maybe I'm overlooking something. However, this single piece of code has shown and taught me things I never knew, so maybe there is something to this. What I would expect is for that overload to always be chosen (not the one with the ... ) because Derived should always have X since it inherits from Fallback . But this is not the case. Can someone please explain why?

Fallback has one data member named X , but Derived will have two if T also has a member named X , in which case Derived::X cannot be taken unambiguously. So if T does not have X , the first overload is used, and if T has X , the second more general version is used. This is why you can tell these cases apart depending on the size of their return types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM