【问题标题】:Are C++ compilers allowed to replace construct + moveconstruct with just a construct? [duplicate]是否允许 C++ 编译器仅用构造替换构造 + 移动构造? [复制]
【发布时间】:2016-09-25 12:24:33
【问题描述】:

是否允许 C++ 编译器替换:

const auto myType = MyType(1, 2, 3);

与:

const MyType myType(1, 2, 3);

即,发出分配,或者有什么可以防止这种情况发生?

注意: 我问的原因是我更喜欢第一个版本。

【问题讨论】:

  • 是的,这就是编译器应该做的,而不是创建一个临时的,然后调用一个复制或移动构造函数。
  • 第一个语法需要一个非显式、非删除和可访问的移动/复制构造函数(尽管它可能在未来发生变化)。
  • 没有赋值,这是初始化。并假设第一个编译,那么是的,编译器可以消除临时。这称为复制省略

标签: c++ c++11 constructor move-constructor copy-elision


【解决方案1】:

是的,允许实现省略类的复制/移动构造 满足某些条件时的对象,称为copy elision

在以下情况下,允许编译器省略 类对象的复制和移动构造函数,即使复制/移动 构造函数和析构函数具有可观察到的副作用。

对于您的代码,

如果一个函数按值返回一个类类型,并且返回 语句的表达式是一个非易失性对象的名称 自动存储时长,不是函数参数,也不是 catch 子句参数,并且具有相同的类型(忽略 顶级 cv-qualification) 作为函数的返回类型,然后 复制/移动被省略。当构造该本地对象时,它是 直接在函数的返回值所在的存储中构造 否则将被移动或复制到。这种复制省略的变体是 称为NRVO,“命名返回值优化”。

请注意,复制/移动 ctor 仍然需要可访问。

即使发生复制省略并且未调用复制/移动构造函数,它也必须存在且可访问(就好像根本没有发生优化一样),否则程序格式错误。

【讨论】:

    猜你喜欢
    • 2010-09-18
    • 2012-05-15
    • 2022-11-21
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    相关资源
    最近更新 更多