为什么 `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 总是会产生一个引用类型,左值引用或右值引用。