ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 完美转发函数以构建函数列表类

2019-08-28 17:07:14  阅读:174  来源: 互联网

标签:perfect-forwarding c c11 function template-meta-programming


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

// 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和universal reference背后发生的所有类型推论.在上面的代码中,我有三个问题:

> _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正在完成这项工作.

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

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基本上通过查看如何推导出T来保留x的类型类别.

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

我认为在你的情况下它应该是std :: tuple< F ...>,因为你想存储左值引用或值.

的std ::元组&LT F&安培;&安培; …&GT将存储左值引用或右值引用 – 这将导致临时引用的悬空引用.

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)…作为其参数,以允许rvalues被转发(即将rvalues移动到function_list的元组中).

标签:perfect-forwarding,c,c11,function,template-meta-programming
来源: https://codeday.me/bug/20190828/1753884.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有