How to detect whether there is a specific member variable in class?
c++, g++, sfinae, templates, visual-studio
Solution
Another way is this one, which relies on SFINAE for expressions too. If the name lookup results in ambiguity, the compiler will reject the template
template<typename T> struct HasX {
struct Fallback { int x; }; // introduce member name "x"
struct Derived : T, Fallback { };
template<typename C, C> struct ChT;
template<typename C> static char (&f(ChT<int Fallback::*, &C::x>*))[1];
template<typename C> static char (&f(...))[2];
static bool const value = sizeof(f<Derived>(0)) == 2;
};
struct A { int x; };
struct B { int X; };
int main() {
std::cout << HasX<A>::value << std::endl; // 1
std::cout << HasX<B>::value << std::endl; // 0
}
It's based on a brilliant idea of someone on usenet.
Note: HasX checks for any data or function member called x, with arbitrary type. The sole purpose of introducing the member name is to have a possible ambiguity for member-name lookup - the type of the member isn't important.
Problem
For creating algorithm template function I need to know whether x or X (and y or Y) in class that is template argument. It may by useful when using my function for MFC CPoint class or GDI+ PointF class or some others. All of them use different x in them. My solution could be reduces to the following code: ``` template<int> struct TT {typedef int type;}; template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; } template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; } struct P1 {int x; }; struct P2 {float X; }; // it also could be struct P3 {unknown_type X; }; int main() { P1 p1 = {1}; P2 p2 = {1}; Check_x(p1); // must return true Check_x(p2); // must return false return 0; } ``` But it does not compile in Visual Studio, while compiling in the GNU C++. With Visual Studio I could use the following template: ``` template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; } template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; } ``` But it does not compile in GNU C++. Is there universal solution? UPD: Structures P1 and P2 here are only for example. There are could be any classes with unknown members. P.S. Please, do not post C++11 solutions here because they are obvious and not relevant to the question.