【问题标题】:What is the reason for `std::result_of` deprecated in C++17?在 C++17 中不推荐使用 `std::result_of` 的原因是什么?
【发布时间】:2018-02-11 18:54:11
【问题描述】:

我看到std::result_of 在 C++17 中已被弃用。

  • std::result_of 在 C++17 中被弃用的原因是什么?
  • 另外我想知道std::result_ofstd::invoke_result之间的区别。

【问题讨论】:

  • 有趣的是,我可以发誓我在那个页面上写了一些东西来解释它为什么被弃用......哦等等,I did
  • 为什么还要将其标记为 C++14?
  • 我刚刚在学习如何使用它。哦,好吧

标签: c++ templates deprecated c++17 result-of


【解决方案1】:

T.C.已经提供了明显的链接,但也许最可怕的原因需要重复:result_of 涉及形成类型 F(Arg1, Arg2, ...) 不是为了那些类型的函数 returning F 而是为了一个函数 类型 F 接受这些类型。 (毕竟,返回类型是result_of 的结果,而不是输入!)

除了与形成函数类型相关的调整之外,两者之间的唯一区别是语法。

【讨论】:

  • 该页面根本没有解释如何使用std::invoke_resultstd::invoke_result_t,只有已弃用的std::result_of
  • @haelix:如果您认为需要,请在此处添加一个示例。我没有写那个页面,解释它的用途与这个问题并不特别相关。
【解决方案2】:

@haelix:

对于 cppreference 页面上缺少示例,我完全同意您的看法。 这是我的看法:

auto add_auto_fn(int a, int b) {
    return a + b;
}

template<typename U, typename V>
auto add_auto_template_fn(U a, V b) {
    return a + b;
}

int fortytwo(int a, int b) { return a + 42; }

struct my_functor{
    auto operator() (int a) { return a + 42; }
};

void test_invoke_result()
{
    {
        // For functions and auto function: use < decltype(&f), Args... >
        using T = std::invoke_result< decltype(&fortytwo), int, int>::type;
        static_assert(std::is_same<T, int>::value, "");
    }
    {
        // For templated auto functions: use < decltype(&f)<Args...>, Args... >
        using T = std::invoke_result< decltype(&add_auto_template_fn<int, double>), int, double>::type;
        static_assert(std::is_same<T, double>::value, "");
    }
    {
        // For simple lambdas: use < decltype(lambda), Args... >
        auto simple_lambda = [](int a) {  return a + 42; };
        using T = std::invoke_result< decltype(simple_lambda), int>::type;
        static_assert(std::is_same<T, int>::value, "");
    }
    {
        // For generic lambdas: use < decltype(lambda), Args... >
        auto generic_lambda = [](auto a) {  return a + 42; };
        using T = std::invoke_result< decltype(generic_lambda), double>::type;
        static_assert(std::is_same<T, double>::value, "");
    }
    {
        // For functors: use < functor, Args... >
        using T = std::invoke_result< my_functor, int>::type;
        static_assert(std::is_same<T, int>::value, "");
    }

}

void test_result_of()
{
    {
        // For functions and auto function: use < decltype(&f)(Args...) >
        using T = std::result_of< decltype(&fortytwo)(int, int)>::type;
        static_assert(std::is_same<T, int>::value, "");
    }
    {
        // For templated auto functions: use < decltype(&f<Args...>)(Args...) >
        using T = std::result_of< decltype(&add_auto_template_fn<int, double>)(int, double)>::type;
        static_assert(std::is_same<T, double>::value, "");
    }
    {
        // For simple lambdas: use < decltype(lambda)(Args...) >
        auto simple_lambda = [](int a) {  return a + 42; };
        using T = std::result_of< decltype(simple_lambda)(int)>::type;
        static_assert(std::is_same<T, int>::value, "");
    }
    {
        // For generic lambdas: use < decltype(lambda)(Args...) >
        auto generic_lambda = [](auto a) {  return a + 42; };
        using T = std::result_of< decltype(generic_lambda)(double)>::type;
        static_assert(std::is_same<T, double>::value, "");
    }
    {
        // For functors: use < functor(Args...) >
        using T = std::result_of< my_functor(int)>::type;
        static_assert(std::is_same<T, int>::value, "");
    }

}

【讨论】:

    【解决方案3】:

    要使用它,你必须改变

    std::result_of_t<A(B)> 
    

    std::invoke_result_t<A, B>
    

    或在模板中

    std::result_of_t<F(Args...)>
    

    std::invoke_result_t<F,Args...>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-17
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-01
      • 2021-01-10
      • 1970-01-01
      相关资源
      最近更新 更多