#include <iostream>
#include <type_traits>
#include <iomanip>
using namespace std;
template<typename T>
bool f(T&& v)
{
return is_function_v<decltype(forward<T>(v))>;
}
int main()
{
cout << boolalpha
<< is_function_v<decltype(setw)>
<< endl;
cout << boolalpha
<< f(setw)
<< endl;
return 0;
}
The outout is: (clang 6.0 & gcc 8.0)
>
true
false
But the result I expect should be:
>
true
true
Why does std::is_function_v
not work as expected?
You need to remove reference on T
.
template<typename T>
bool f(T&& v)
{
return is_function_v<remove_reference_t<decltype(forward<T>(v))>>;
// ~~~~~~~~~~~~~~~~~~
}
When pass setw
to f
, it's an lvalue, then the forwarding reference type T
will be deduced as an lvalue reference to function. For std::is_function
, references to function (and pointers to function etc) don't count as function types.
BTW: the forwarding reference type T
will be deduced as either lvalue reference or rvalue reference; and using decltype
on std::forward
would always yield a reference type, either lvalue reference or rvalue reference.