I am learning writing my own traits using C++11 borrowing only std::true_type
and std::false_type
.
I've created the following trait:
#include <iostream>
template <typename F>
struct is_farg1: std::false_type {};
template <typename R, typename A>
struct is_farg1<R (*)(A)> : std::true_type {};
Now consider a program including the above trait, and the following code:
void f(int) {}
int main() {
std::cout << "is_farg1<decltype(f)> : " << is_farg1<decltype(f)>::value << std::endl;
std::cout << "is_farg1<void(*)(int)> : " << is_farg1<void(*)(int)>::value << std::endl;
return 0;
}
It produces the following output:
is_farg1<decltype(f)> : 0
is_farg1<void(*)(int)> : 1
My questions:
is_farg1<void(*)(int)>::value
is true
while is_farg1<decltype(f)>::value
returned false
?decltype(f)
?Becasue decltype(f)
gives the exact function type (i.e. void(int)
) but not the function pointer type (i.e. void(*)(int)
). When decltype
is used for entity,
If the argument is an unparenthesized id-expression or an unparenthesized class member access expression, then
decltype
yields the type of the entity named by this expression.
You can add another specialization for the function type like
template <typename R, typename A>
struct is_farg1<R (A)> : std::true_type {};
Or check the type as function pointer like
is_farg1<decltype(f)*>::value
// ^
// or
is_farg1<decltype(&f)>::value
// ^