2016-03-24 11 views
5

Mam w następstwie realizacji is_function:Implementacja std :: is_function - dlaczego moja implementacja działa inaczej?

template <typename SomeType> 
struct _is_function_helper : public _false_expression {}; 
template <typename ReturnType, typename ... ArgumentTypes> 
struct _is_function_helper<ReturnType (ArgumentTypes ...)> : _true_expression {}; 
template <typename ReturnType, typename ... ArgumentTypes> 
struct _is_function_helper<ReturnType (ArgumentTypes ..., ...)> : _true_expression {}; 

template <typename SomeType> 
struct _is_function : public _boolean_expression<_is_function_helper<typename _remove_cv<typename _remove_reference<SomeType>::Type>::Type>::value> {}; 

usunąć referencje, kwalifikatorów cv a następnie spróbuj dziedziczą od samego wyrażenia bool jako _is_function_helper będzie. Potem próbowałem następujące testy:

void func(int,int) { }; 

struct A { void foo(int); }; 

.... 

auto r = func; 
std::cout << std::boolalpha; 
std::cout << std::is_function<decltype(func)>::value << " " << _is_function<decltype(func)>::value << std::endl; 
std::cout << std::is_function<int(int)>::value << " " << _is_function<int(int)>::value << std::endl; 
std::cout << std::is_function<int(*)(int)>::value << " " << _is_function<int(*)(int)>::value << std::endl; 
std::cout << std::is_function<decltype(r)>::value << " " << _is_function<decltype(r)>::value << std::endl; 
std::cout << std::is_function<decltype(*r)>::value << " " << _is_function<decltype(*r)>::value << std::endl; 
std::cout << std::is_function<decltype(&A::foo)>::value << " " << _is_function<decltype(&A::foo)>::value << std::endl; 

i tu jest wyjście z tych testów:

true true 
true true 
false false 
false false 
false true 
false false 

Mam dwa pytania:

  1. Dlaczego jest wyprowadzany w 5 przypadku testowego inaczej?
  2. Jak można wykryć funkcję elementu struct za pomocą _is_function?

Odpowiedz

5

Wyjście w 5. przypadku jest inne, ponieważ decltype(*r) jest odniesieniem do funkcji. Twoja implementacja usuwa to odwołanie, ale nie ma go.

Można wykryć wskaźnik funkcji członek dodając specjalizacji tak:

template <typename ReturnType, typename ... ArgumentTypes, typename T> 
struct _is_function_helper<ReturnType (T::*) (ArgumentTypes ...)> 
    : _true_expression {}; 
+0

ah dzięki myślałem powinien wykryć również funkcjonować referencje według tego http://en.cppreference.com/w/cpp/types/is_function –