Element Detection Code Explanation

This is not a concept in general, but one of the methods that it uses to determine if a class has data element n . Here is the complete code; The usual use of SFINAE to detect an item.

 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 on which Derived inherits from both Fallback and T confuses me, because when we overload f , &C::X is &Derived::X But shouldn't this overload always be chosen because it isn’t guaranteed that Derived has X , since it inherits from Fallback , which has this data element?

Maybe I'm missing something. However, this single piece of code showed and taught me things that I never knew, so there might be something in it. I would expect that overload will always be selected, not the one that has ... ), because Derived should always have X , since it inherits from Fallback . But this is not so. Can someone explain why?

+7
source share
1 answer

Fallback has one data item named X , but Derived will have two if T also has a member named X , in which case Derived::X cannot be taken unambiguously. Therefore, 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 separate these cases depending on the size of the return types.

+3
source

All Articles