Проверка наличия у аргумента шаблона функции-члена

Возможный дубликат:
Можно ли написать шаблон C++ для проверки существования функции?

Это очень похоже на мой предыдущий вопрос . Я хочу проверить, содержит ли аргумент шаблона функцию-член или нет.

Я попробовал этот код, аналогичный коду в принятом ответе на мой предыдущий вопрос.

struct A
{
   int member_func();
};

struct B
{
};

template<typename T>
struct has_member_func
{
   template<typename C> static char func(???); //what should I put in place of '???'
   template<typename C> static int func(...);

   enum{val = sizeof(func<T>(0)) == 1};
};

int main()
{
    std::cout<< has_member_func<B>::val; //should output 0
    std::cout<< has_member_func<A>::val; //should output 1
}

Но я понятия не имею, что я должен поставить вместо ???, чтобы это заработало. Я новичок в концепции SFINAE.


person NEWBIE    schedule 04.12.2010    source источник
comment
Используйте что-то похожее на HAS_MEM_FUNC, которое Йоханнес опубликовал в этой теме. Я использовал этот код раньше, и он отлично работает.   -  person Nathan Pitman    schedule 04.12.2010
comment
icecrime Спасибо, что указали, что это дубликат. Однако в принятом ответе используется нестандартный оператор typeof. Можете ли вы предложить альтернативу? Согласно комментарию MSalter static char func(char[sizeof(&C::helloworld)]) должен работать?   -  person NEWBIE    schedule 04.12.2010
comment
@NEWBIE: см. ответ Йоханнеса, так намного лучше   -  person icecrime    schedule 04.12.2010
comment
icecrime извините, но его решение слишком запутанное. Можете ли вы предложить что-то похожее на принятое решение в исходной ссылке?   -  person NEWBIE    schedule 04.12.2010
comment
@NEWBIE: посмотрите ответ @FireAphis. Это намного проще, чем ответ Йоханнеса. :)   -  person Prasoon Saurav    schedule 04.12.2010
comment
@Prasoon изменения, которые он внес, создают две проблемы: TypeHasToString может не скомпилироваться с типами, не относящимися к классу (он не будет использовать SFINAE, когда ошибка возникает внутри ToString<>), и произойдет сбой, если sizeof(char) == sizeof(long). Я изменю свой ответ, чтобы использовать typedefs, чтобы он был более читабельным.   -  person Johannes Schaub - litb    schedule 05.12.2010
comment
@NEWBIE, это это сложная тема, для которой, скорее всего, нет простого решения. Если этот материал слишком запутан для вас, возможно, это знак, что вам не следует его использовать, а нужно попытаться решить проблему другим способом.   -  person Johannes Schaub - litb    schedule 05.12.2010


Ответы (1)


Небольшая модификация идеи MSalters из Можно ли написать шаблон C++ для проверки существования функций? :

template<typename T>
class has_member_func
{
        typedef char no;
        typedef char yes[2];
        template<class C> static yes& test(char (*)[sizeof(&C::member_func)]);
        template<class C> static no& test(...);
public:
        enum{value = sizeof(test<T>(0)) == sizeof(yes&)};
};
person Pawel Zubrycki    schedule 04.12.2010
comment
Я получаю эту ошибку с GCC 4.2.1: In instantiation of ‘has_member_func<Duck>’: error: array bound is not an integer constant - person nilton; 27.06.2011