为什么`std :: is_function_v`无法按预期工作?

xml*_*lmx 4 c++ standards templates type-traits c++11

#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;
}
Run Code Online (Sandbox Code Playgroud)

结果是:(clang 6.0&gcc 8.0)

>

真正

但我期望的结果应该是:

>

真正

真正

为什么不std::is_function_v按预期工作?

son*_*yao 5

您需要删除参考T.

template<typename T>
bool f(T&& v)
{
    return is_function_v<remove_reference_t<decltype(forward<T>(v))>>;
    //                   ~~~~~~~~~~~~~~~~~~
}
Run Code Online (Sandbox Code Playgroud)

传递setwf它时,它是一个左值,然后转发引用类型T将被推导为函数的左值引用.因为std::is_function,函数(和函数指针等)的引用不算作函数类型.


BTW:转发引用类型T将推导为左值引用或右值引用; 并且使用decltypeon std::forward将始终产生一个引用类型,左值引用或右值引用.

  • 为什么要转发它然后删除引用?为什么你甚至会使用decltype而不是直接在类型T上删除ref? (6认同)