在 C++17 中弃用"std::result_of"的原因是什么?



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

  • std::result_ofC++17 中弃用的原因是什么?
  • 我也想知道std::result_ofstd::invoke_result之间的区别。

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

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

@haelix:

关于 cpp首选项页面上缺乏示例,我完全同意您的看法。 这是我的看法:

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, "");
}
}

要使用它,您必须从

std::result_of_t<A(B)> 

std::invoke_result_t<A, B>

或在模板中

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

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

这在 cpp 首选项上得到了很好的解释:

F(Args...)是一种函数类型,Args...是参数类型,F是返回类型.
因此,std::result_of遭受了几个怪癖,导致它在 C++17 中弃用以支持std::invoke_result

  • F不能是函数类型或数组类型(但可以是对它们的引用);
  • 如果任何Args具有"T数组"类型或函数类型T,则会自动调整为T*;
  • FArgs...中的任何一个都不能是抽象类类型;
  • 如果Args...中的任何一个具有顶级 CV 限定符,则将其丢弃;
  • Args...都可能不属于void型。

相关内容

  • 没有找到相关文章

最新更新