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

时间:2018-09-10 03:16:02

标签: c++ c++11 templates standards typetraits

#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不能按预期工作?

1 个答案:

答案 0 :(得分:5)

您需要删除对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,对函数的引用(以及对函数的指针等)不算作函数类型。


BTW:转发引用类型T将被推导为左值引用或右值引用;并在decltype上使用std::forward总是会产生引用类型,即左值引用或右值引用。