Oops. There is a problem though, that the code fails to compile, when a class does not have a member with that name at all

...
Здравствуйте, Cruelty, Вы писали:
C>Oops. There is a problem though, that the code fails to compile, when a class does not have a member with that name at all
...
Ничего не поделаешь. Баг в алгоритме унификации типа вида R (T::*). Для метода-члена работает R (T::*)(),просто для R (T::*) данных нет.
Вот код основанный на немного другой идее — результат тот же.
#include <iostream>
template<class T,class R, R (T::* t)()=&T::member>
class member_bind
{
public:
typedef T type;
};
template<class T1,class R, class T2>
class has_member
{
public:
static const bool value = false;
};
template<class T,class R>
class has_member<T,R,typename member_bind<T,R>::type>
{
public:
static const bool value = true;
};
struct X{};
class A
{
public:
X member();
};
class B {};
class C
{
public:
int member();
};
int main(int argc, char* argv[])
{
std::cout << "A has member? " << (has_member<A,X,A>::value ? "yes" : "no") << std::endl;
std::cout << "B has member? " << (has_member<B,X,B>::value ? "yes" : "no") << std::endl;
std::cout << "C has member? " << (has_member<C,int,C>::value ? "yes" : "no") << std::endl;
return 0;
}
Здравствуйте, Cruelty, Вы писали:
C>Oops. There is a problem though, that the code fails to compile, when a class does not have a member with that name at all
...
Вот рабочий код для VC9. g++ ругается, надо причесывать. ICL лажает.
#include <iostream>
#include <string>
struct Yes{int i;};
struct No{Yes i[10];};
template< typename T,typename R > No Helper(...){return No();}
template< typename T,typename R > Yes Helper(R (T::*)){return Yes();}
struct Dummy{};
template<int i>
struct X
{
typedef Dummy type;
};
template<>
struct X<sizeof(Yes)>
{
typedef int* type;
};
template<typename T,typename R> No Finder(...){return No();}
template<typename T,typename R> Yes Finder(typename X<sizeof(Helper<T,R>(&T::b))>::type p){return Yes();}
struct A { int b; };
struct B { };
struct C { B b; };
struct D { double* b; };
int main()
{
std::cout << (sizeof(Finder<A,int>(0))==sizeof(Yes)) << std::endl;
std::cout << (sizeof(Finder<B,int>(0))==sizeof(Yes)) << std::endl;
std::cout << (sizeof(Finder<C,B>(0))==sizeof(Yes)) << std::endl;
std::cout << (sizeof(Finder<D,double*>(0))==sizeof(Yes)) << std::endl;
}
Вывод
1
0
1
1