为什么 `std::is_function_v` 没有按预期工作?
Why does `std::is_function_v` not work as expected?
#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;
}
结果是:(clang 6.0 & gcc 8.0)
>
true
false
但我期望的结果应该是:
>
true
true
为什么 std::is_function_v
没有按预期工作?
您需要删除对 T
的引用。
template<typename T>
bool f(T&& v)
{
return is_function_v<remove_reference_t<decltype(forward<T>(v))>>;
// ~~~~~~~~~~~~~~~~~~
}
当setw
传递给f
时,它是一个左值,那么转发引用类型T
将被推导为函数的左值引用。对于 std::is_function
,对函数的引用(以及指向函数的指针等)不算作函数类型。
顺便说一句:转发引用类型 T
将被推断为左值引用或右值引用;并且在 std::forward
上使用 decltype
总是会产生一个引用类型,左值引用或右值引用。
#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;
}
结果是:(clang 6.0 & gcc 8.0)
>
true
false
但我期望的结果应该是:
>
true
true
为什么 std::is_function_v
没有按预期工作?
您需要删除对 T
的引用。
template<typename T>
bool f(T&& v)
{
return is_function_v<remove_reference_t<decltype(forward<T>(v))>>;
// ~~~~~~~~~~~~~~~~~~
}
当setw
传递给f
时,它是一个左值,那么转发引用类型T
将被推导为函数的左值引用。对于 std::is_function
,对函数的引用(以及指向函数的指针等)不算作函数类型。
顺便说一句:转发引用类型 T
将被推断为左值引用或右值引用;并且在 std::forward
上使用 decltype
总是会产生一个引用类型,左值引用或右值引用。