Re[3]: Как такое починить на MSVC?
От: Cruelty  
Дата: 19.01.10 12:42
Оценка:
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 ...
Re[4]: Как такое починить на MSVC?
От: D14  
Дата: 19.01.10 14:09
Оценка:
Здравствуйте, 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;
}
Re[4]: Как такое починить на MSVC?
От: D14  
Дата: 19.01.10 15:59
Оценка: 12 (1)
Здравствуйте, 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
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.