views:

66

answers:

1

Hello,

I was trying to figure out if it is possible to use sfinae to test namespace member existence. Google is rather silent about it. I've tried the following code, but it fails.

namespace xyz{
 struct abc{};
}

struct abc{};

struct test_xyz{ 
 typedef char yes;
 typedef struct{ char a[2]; } no;

 template <class C> static yes test(xyz::C = xyz::C()); //lets assume it has default constructor
 template <class C> static no test(...);

 const bool has_abc = sizeof(test_xyz::test<abc>()) == sizeof(yes);
};

Any idea why?

Regards,

+5  A: 

No, that won't work. There is also no way to use SFINAE in such a way (this was last discussed on usenet for a compatibility test against some C++0x component). The C inside xyz::C is not related to the template parameter at all.

Remember that templates are not just macros. The parameter C denotes not just a piece of text, but a semantical entity. In this case it is a type. It's bound already to the meaning it has as an argument. That is, if your class had a member of name abc, the meaning of the parameter still would not change.

If all you want is to use some struct xyz::abc if it exists, and others::abc otherwise, you can do some tricks to get there, but I'm not aware of a way that does it without touching xyz

namespace others {
  struct abc{};
}

namespace fallbacks {
  using others::abc;
}

namespace xyz {
  using namespace fallbacks;
}

Now if you say xyz::abc and xyz contains a member declared so, it will refer to that member (that member will hide the one in fallbacks. However if it doesn't contain that member, then the using directive's name will be found and refer to fallbacks::abc.

Johannes Schaub - litb