C++11 最优参数传递

2023-11-27

考虑这些类:

#include <iostream>
#include <string>

class A
{
    std::string test;
public:
    A (std::string t) : test(std::move(t)) {}
    A (const A & other) { *this = other; }
    A (A && other) { *this = std::move(other); }

    A & operator = (const A & other)
    {
        std::cerr<<"copying A"<<std::endl;
        test = other.test;
        return *this;
    }

    A & operator = (A && other)
    {
        std::cerr<<"move A"<<std::endl;
        test = other.test;
        return *this;
    }
};

class B
{
    A a;
public:   
    B (A && a) : a(std::move(a)) {}
    B (A const & a) : a(a) {}
};

当创建一个B,我总是有一个最佳的前进路径A,右值的一次移动或左值的一份副本。

是否可以用一个构造函数达到相同的结果?在这种情况下问题不大,但是多个参数怎么办?我需要参数列表中所有可能出现的左值和右值的组合。

这不仅限于构造函数,还适用于函数参数(例如 setter)。

注意:这个问题严格来说是关于class B; class A存在只是为了可视化复制/移动调用是如何执行的。


“按值”方法是一种选择。它并不像您所拥有的那样优化,但只需要一次重载:

class B
{
    A a;
public:   
    B (A _a) : a(move(_a)) {}
};

对于左值和 x 值来说,成本都是 1 次额外的移动构造,但这对于纯右值来说仍然是最佳的(1 次移动)。 “xvalue”是已使用 std::move 转换为右值的左值。

您也可以尝试“完美转发”解决方案:

class B
{
    A a;
public:   
    template <class T,
              class = typename std::enable_if
              <
                 std::is_constructible<A, T>::value
              >::type>
    B (T&& _a) : a(std::forward<T>(_a)) {}
};

这将使您回到复制/移动结构的最佳数量。但是您应该限制模板构造函数,使其不会过于通用。您可能更喜欢使用 is_convertible 而不是 is_constructible,就像我上面所做的那样。这也是单个构造函数解决方案,但随着您添加参数,您的约束变得越来越复杂。

Note:上面的约束是必要的,因为如果没有,客户B当他们查询时会得到错误的答案std::is_constructible<B, their_type>::value。如果没有适当的约束,它会错误地回答 trueB.

我想说的是,这些解决方案并不总是比其他解决方案更好。这里需要进行工程权衡。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11 最优参数传递 的相关文章

随机推荐

  • 如何在生产中禁用转储 symfony 功能

    如何禁用dump 功能 什么时候在生产环境中 如果我忘记了转储功能 它会崩溃并出现 500 错误 你应该删除dump 来自您的生产代码 它不必在那里 But as noted by Cerad 因为当您在签入之前忘记删除它们时可能会很烦人
  • 我如何告诉 PyCharm 参数的预期类型是什么?

    当涉及到构造函数 赋值和方法调用时 PyCharm IDE 非常擅长分析我的源代码并找出每个变量应该是什么类型 我喜欢它正确的时候 因为它为我提供了良好的代码完成和参数信息 并且如果我尝试访问不存在的属性 它会给我警告 但当涉及到参数时 它
  • 映射缩减组合器

    我有一个带有映射器 减速器和组合器的简单映射缩减代码 映射器的输出被传递到组合器 但是对于reducer来说 传递的不是combiner的输出 而是mapper的输出 请帮忙 Code package Combiner import jav
  • 如何在 React Native 中限制 google 登录到我公司的电子邮件域 (@company.com)?

    Question 阻止用户使用不以 mycompany com 结尾的电子邮件地址通过 Firebase Google 身份验证登录我们的内部应用程序的最佳方法是什么 Goal 防止用户使用错误的电子邮件登录应用程序 获取用户的公司电子邮件
  • Python pip install 以“命令错误,退出状态 1:...”结束

    我是 python 新手 我正在尝试运行一些需要一些库的基本代码 当我尝试安装库 例如 pip install matplotlib venn 时 我收到这个长错误 ERROR Command errored out with exit s
  • 如何使用 JavaScript 以编程方式打开文件选择器? [复制]

    这个问题在这里已经有答案了 可能的重复 在 JavaScript 中 我可以通过编程方式为文件输入元素触发 click 事件吗 我天真地尝试了以下方法 使用 JavaScript 以编程方式打开文件选择器 请参阅 fiddlehere
  • 每当 firebase 发生任何更改时,自动向所有用户发送通知 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 当 Firebase 发生更改时 如何通知所有用户 我不想手动执行此操作 您应该使用由实时数据库触发器触发的 Firebase Cloud Function 请参阅文档here
  • 如何启动Manifest中提到的不存在的Activity?

    我正在尝试开发一个 动态 Android 应用程序 动态是指我在清单中列出了一个在运行时 构建 的活动 我可以很好地构建所需的活动 但是 当我尝试启动它时 我的应用程序失败了 java lang RuntimeException Unabl
  • std::sort 会改变相等元素的相对顺序吗?

    标准是否通过使用 std sort 保证相等元素的顺序不会改变 呃 忘记了这个术语 或者我是否需要考虑替代解决方案来实现此目标 std sort不保证稳定 您试图想到的术语 正如你猜想的那样 std stable sort保证稳定 std
  • 如何更改AlertDialog中的文本颜色

    如何更改 AlertDialog 中的文本颜色
  • 如何使中心裁剪图像响应?

    基于一个现有答案 我已经设法居中裁剪图像 不过 我在使中心裁剪图像具有响应能力时遇到了困难 Question 当我减小网络浏览器窗口的大小时 中心裁剪图像不能很好地缩小 相反 它保持固定状态height and width and spil
  • 多重继承的虚方法表

    我正在读这篇文章 虚拟方法表 上面文章中的例子 class B1 public void f0 virtual void f1 int int in b1 class B2 public virtual void f2 int int in
  • 在组件状态下从数组中删除元素

    我正在尝试找到在组件状态下从数组中删除元素的最佳方法 因为我不应该修改this state直接变量 是否有比我这里更好的方法 更简洁 从数组中删除元素 onRemovePerson function index this setState
  • 断言失败:预测必须 >= 0,条件 x >= y 不按元素成立

    我正在运行一个多类模型 总共 40 个类 2000 个时期 该模型在 828 纪元之前运行良好 但在 829 纪元时它给了我一个 InvalidArgumentError 参见下面的屏幕截图 下面是我用来构建模型的代码 n cats 40
  • 获取 IndexedDB 中添加记录的键

    我在 IndexedDB 中有这段代码 var request objectStore add entryType entryType entryDate t 现在我想知道刚刚添加的这条记录的密钥 我该怎么做 I found 本文 和这个
  • iOS 版 GoogleMaps SDK 上是否存在标记动画?

    是否可以移动 旋转GMSMarker on GMSMapView有动画 1 2 中的补充是GMSMarker类有一个animated属性 我想你刚刚将其设置为YES 在通过设置其标记将标记添加到地图之前map属性 虽然我还没有尝试过 htt
  • 如何将原子计数器添加到 powershell ForEach -Parallel 循环

    在这个问题中 解释了如何添加到并发ThreadSafe集合Powershell 如何将结果添加到数组 ForEach Object Parallel 我有一个更简单的用例 我只想增加一个值 整数 是否可以在 Powershell 中使用某种
  • PerformSelector:withObject: 及其保留行为

    这是SO中已经回答的问题但是我在 Apple 文档中找不到它 你能指出我正确的方向吗 在以下主题中 在将对象传递给 performSelector withObject afterDelay 之前是否必须保留该对象 对 PerformSel
  • 如何对可变参数模板函数的异构参数包进行通用计算?

    PREMISE 在尝试了一下可变参数模板之后 我意识到实现任何稍微超出微不足道的元编程任务的东西很快就会变得相当麻烦 特别是 我发现自己希望有一种方式来表现对参数包的通用操作例如iterate split loop in a std for
  • C++11 最优参数传递

    考虑这些类 include