即使XZY具有非复制约束,构造助手make_XYZ也允许RVO和类型推导

Pat*_*erg 13 c++ rvalue-reference c++11 return-type-deduction c++17

UPDATE1: C++ 17构造附加型扣-这并不意味着自由功能是较差的溶液.

UPDATE2: C++ 17增加了保证副本省略(副本甚至没有在概念上发生).因此,使用C++ 17,我的代码实际上可以工作并具有最佳性能.但Martinho使用支撑初始化来获得返回值的代码仍然是我认为的更清洁的解决方案.但请查看Barry的回答以及TC的评论

旧帖子:类型推导不适用于构造函数(至少在包含C++ 11之前).常见的解决方案是依靠RVO(返回值优化)并编写make_XYZ模板函数,将其参数转发给构造函数.一个例子是std::make_tuple.

任何模板acrobat谁知道一个解决方法,以便在nocopy策略阻碍时使其工作?有效的解决方案仍然必须允许RVO发生.

另外,对于任何make_XYZ的要求是否会随C++ 14消失?

#include <iostream>

template <typename T>
struct XYZ
{
    // remove following two lines to make the code compile
    XYZ (XYZ const & rhs) = delete; 
    XYZ (XYZ && rhs) = delete; 
    T i;
    XYZ (T i):i(i)
    {
    }
};

template <typename T>
XYZ<T> make_XYZ (T && i)
{
    return XYZ<T>(std::forward<T>(i));
}

int main ()
{
    auto x = make_XYZ(1);
    std::cout << x.i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

R. *_*des 20

如果存在非显式构造函数,则确实可以按值返回不可复制和不可移动的类型.请参阅实例:http://coliru.stacked-crooked.com/a/89ef9d3115924558.

template <typename T>
XYZ<T> make_XYZ (T && i)
{
    return { std::forward<T>(i) };
}
Run Code Online (Sandbox Code Playgroud)

这里棘手的一点是,{ ... }它不是构造一个临时的并将其移动到返回值.它直接初始化返回值.没有复制也没有移动,这与是否适用任何优化无关(如果需要优化才能编译).

但是,由于类型不可复制也不可移动,因此您无法按值将其存储在本地变量中.但是,您可以使用旧的临时生命周期扩展技巧来保存它:

auto&& x = make_XYZ(1);
Run Code Online (Sandbox Code Playgroud)

  • 问题是:"有效的解决方案仍然必须允许RVO发生!" - 这个答案是为什么基本上应该忽略对问题答案的任意限制,以及为什么SO要求实际问题.:) (3认同)
  • 我知道这违反了评论惯例.但我无法掩饰它.我很佩服! (2认同)

归档时间:

查看次数:

715 次

最近记录:

7 年,8 月 前