Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of std::is_function - why my implementation behaves differently?

I have following implementation of is_function:

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

I remove references, cv qualifiers and then try to inherit from same bool expression as _is_function_helper would. Then I tried following tests:

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;

And here is output of these tests:

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

I have two questions:

  1. Why is output in 5th test case different?
  2. How is it possible to detect member function of struct using _is_function?
like image 562
Alexander Bily Avatar asked Mar 24 '16 12:03

Alexander Bily


1 Answers

The output in the 5th case is different because decltype(*r) is a reference to a function. Your implementation removes this reference, but std::is_function does not.

You can detect a member function pointer by adding a specialization like this:

template <typename ReturnType, typename ... ArgumentTypes, typename T>
struct _is_function_helper<ReturnType (T::*) (ArgumentTypes ...)> 
    : _true_expression {};
like image 132
TartanLlama Avatar answered Nov 14 '22 22:11

TartanLlama