【问题标题】:How to use std::invoke_result_t in c++17 or 20 instead of std::result_of_t in c++14?如何在 c++17 或 20 中使用 std::invoke_result_t 而不是 c++14 中的 std::result_of_t?
【发布时间】:2021-12-02 12:02:15
【问题描述】:

当我在 c++14 中使用 std::result_of_t 时,它正在按照我的意愿进行:

void just_simple()
{
    std::cout << "【4】: in func return nothing. " << std::endl;
}

template<typename Callback, typename... Args>
auto InTemplate_Call(Callback&& bc, Args&&... args)
{
    typedef typename std::result_of_t<std::decay_t<Callback>(std::decay_t<Args>...)> ReturnType;

    //typedef typename std::invoke_result_t<std::decay_t<Callback>(std::decay_t<Args>...)> ReturnType;

    if (typeid(ReturnType) == typeid(void))
    {
        std::cout << "get a void type" << std::endl;
    }

    return rtDeduction<ReturnType>::type();
}

int main(){
    InTemplate_Call(just_simple);

    return 0;
}

ReturnType 就是 void

但它不适用于 c++17 或 20:

template<typename Callback, typename... Args>
auto InTemplate_Call(Callback&& bc, Args&&... args)
{
    //typedef typename std::result_of_t<std::decay_t<Callback>(std::decay_t<Args>...)> ReturnType;

    typedef typename std::invoke_result_t<std::decay_t<Callback>(std::decay_t<Args>...)> ReturnType;

    if (typeid(ReturnType) == typeid(void))
    {
        std::cout << "get a void type" << std::endl;
    }

    return rtDeduction<ReturnType>::type();
}

ReturnType 不再是void

有什么我做错了吗?

【问题讨论】:

    标签: c++ c++17 c++14 metaprogramming c++20


    【解决方案1】:

    invoke_resultresult_of 的区别在于前者接受可调用类型和参数类型,而您的std::decay_t&lt;Callback&gt;(std::decay_t&lt;Args&gt;...) 只是一个返回std::decay_t&lt;Callback&gt;函数类型

    以下显示了差异:

    #include <functional>
    
    void just_simple() {}
    
    template<typename Callback>
    void foo(Callback&&)
    {
      static_assert(std::is_same_v<std::invoke_result_t<Callback()>, Callback>);
      static_assert(std::is_same_v<std::invoke_result_t<Callback  >, void>);
    }
    
    int main() {
      foo(just_simple);
    }
    

    你应该这样做:

    typedef typename std::invoke_result_t<
      std::decay_t<Callback>, 
      std::decay_t<Args>...> ReturnType;
    

    【讨论】:

    • typename 关键字是不必要的。还认为usingtypedef 更容易阅读,因为这里已经假设了 C++11,但我想这是个人喜好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 2020-10-29
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多