【问题标题】:Why does `std::is_function_v` not work as expected?为什么 `std::is_function_v` 不能按预期工作?
【发布时间】:2019-02-14 11:08:39
【问题描述】:
#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)

>

是的

但我期望的结果应该是:

>

是的

是的

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

【问题讨论】:

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


    【解决方案1】:

    您需要删除对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 总是会产生一个引用类型,左值引用或右值引用。

    【讨论】:

    • 为什么要转发它然后删除参考?为什么你甚至要使用 decltype 而不是直接在类型 T 上删除 ref?
    猜你喜欢
    • 1970-01-01
    • 2020-06-07
    • 2016-09-27
    • 2021-05-30
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多