2010-08-30 3 views
5

Estaba tratando de averiguar si es posible usar sfinae para probar espacio de nombres existencia del miembro. Google guarda silencio al respecto. Probé el siguiente código, pero falla.use sfinae para probar la existencia de miembros del espacio de nombres

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

¿Alguna idea de por qué?

Saludos,

Respuesta

10

No, eso no funcionará. Tampoco hay forma de utilizar SFINAE de tal manera (esto fue discutido por última vez en usenet para una prueba de compatibilidad contra algún componente de C++ 0x). El C dentro de xyz::C no está relacionado con el parámetro de plantilla en absoluto.

Recuerde que las plantillas no son solo macros. El parámetro C denota no solo una pieza de texto, sino una entidad semántica. En este caso, es un tipo. Ya está relacionado con el significado que tiene como argumento. Es decir, si su clase tenía un miembro con el nombre abc, el significado del parámetro aún no cambiaría.

Si lo que quieres es usar alguna estructura xyz::abc si existe, y others::abc de lo contrario, puede hacer algunos trucos para llegar allí, pero no estoy al tanto de una manera que lo hace sin tocar xyz

namespace others { 
    struct abc{}; 
} 

namespace fallbacks { 
    using others::abc; 
} 

namespace xyz { 
    using namespace fallbacks; 
} 

Ahora si dice xyz::abc y xyz contiene un miembro declarado así, se referirá a ese miembro (ese miembro ocultará el que está en fallbacks. Sin embargo, si no contiene ese miembro, se encontrará el nombre de la directiva de uso y refiérase a fallbacks::abc.

Cuestiones relacionadas