gpt4 book ai didi

c++ - 功能完美转发构建功能列表类

转载 作者:太空狗 更新时间:2023-10-29 20:35:36 25 4
gpt4 key购买 nike

考虑以下构建类存储函数的代码。

// Function list class
template <class... F>
struct function_list
{
template <class... G>
constexpr function_list(G&&... g) noexcept
: _f{std::forward<G>(g)...}
{
}
std::tuple</* F... OR F&&... */> _f;
};

// Function list maker
template <class... F, class R = /* Can we compute the return type here? */>
constexpr R make_function_list(F&&... f)
{
return function_list<
/* decltype(std::forward<F>(f))...
* OR F...
* OR F&&...
*/>(std::forward<F>(f)...);
}

我希望这些函数能够完美转发(不管它们是函数指针、仿函数、lambdas...)。但我并不完全理解 std::forward 背后发生的所有类型推导。和通用引用。在上面的代码中,我有三个问题:

  • 应该_f类型为 std::tuple<F...>std::tuple<F&&...> (为什么?)
  • 是否可以推导出返回类型 R在模板参数列表中(因为手动而不是 auto/decltype(auto) 将有助于理解正在发生的事情)
  • 在制造商中,function_list 是什么模板参数应为:decltype(std::forward<F>(f)...) , F , 或 F&&... (为什么?)

注:function_list的构造函数并不意味着直接调用,而是 make_function_list正在做这项工作。

编辑:这种情况安全吗,当operator()function_list (此处未显示)不保证在同一语句中被调用?

template <class... F>
constexpr function_list<F...> make_function_list(F&&... f)
{
return function_list<F&&...>(std::forward<F>(f)...);
}

最佳答案

But I don't exactly understand all the type deduction happening behind std::forward and universal references.

通过一个例子就很容易理解了。

template <typename T>
void f(T&&)
{
std::tuple<T>{}; // (0)
std::tuple<T&&>{}; // (1)
}

对于(0):

  • T推导为 T对于右值
  • T推导为 T&对于左值

对于(1):

  • T推导为 T&&对于右值
  • T推导为 T&对于左值

如您所见,两者之间的唯一区别是右值的推导方式。

关于 std::forward ,这就是它的作用:

template <typename T>
void g(T&&);

template <typename T>
void f(T&& x)
{
g(x) // (0)
g(std::forward<T>(x)); // (1)
}

对于(0):

  • x始终是一个左值

对于(1):

  • x被转换到 T&&如果T推导为 T .

  • x否则保持左值

std::forward基本保留了x的类型分类通过查看如何 T被推导出来。


Should _f be of type std::tuple<F...> or std::tuple<F&&...>

我认为你的情况应该是 std::tuple<F...> ,因为您要存储左值引用

std::tuple<F&&...>将存储左值引用右值引用 - 在临时对象的情况下会导致悬空引用


Is it possible to deduce the return type R in the template parameter list

是的,就是function_list<F...> .

template <class... F, class R = function_list<F...>>
constexpr R make_function_list(F&&... f)
{
return function_list<F...>(std::forward<F>(f)...);
}

你甚至不需要 R模板参数。

template <class... F>
constexpr function_list<F...> make_function_list(F&&... f)
{
return function_list<F...>(std::forward<F>(f)...);
}

In the maker, what the function_list template argument should be: decltype(std::forward<F>(f)...), F, or F&&...

function_list应该采取 F...出于本答案开头列出的原因作为模板参数(即避免对临时对象的悬空引用)

它仍然需要 std::forward<F>(f)...作为允许右值被转发的参数(即将右值移动到function_list的元组中)

关于c++ - 功能完美转发构建功能列表类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42032755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com