c++ - 编译器在 std::move 和 deleted 复制构造函数方面的行为不同

标签 c++ c++17

#include <utility>

struct A {};

struct B {
  B(A&&) {}
  B(const B&) = delete;
};

static void func(B) {}

int main() {
  A a;
  func(std::move(a));
}

此程序被接受:

  • 自 7.1 以来的 GCC 与 -std=c++17
  • GCC 主干(可能默认使用 C++17?)
  • 从 5.0 开始使用 -std=c++17
  • MSVC 我能找到的所有版本。

C++17 中关于此的标准是否发生了变化? MSVC 在 C++17 之前接受这个是错误的吗?

最佳答案

MSVC 错误。对于 guaranted copy elision自 C++17 以来,

The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible:

  • In the initialization of an object, when the initializer expression is a prvalue of the same class type (ignoring cv-qualification) as the variable type:

给定func(std::move(a));std::move(a)用于构造一个临时的B 首先通过 B::B(A&&),然后通过 B::B(const B&) 将临时对象作为参数复制到 func >。完全省略复制操作,参数由std::move(a)直接通过B::B(A&&)构造。

在 C++17 之前,这是一种优化,复制/移动构造函数仍然必须存在且可访问。

关于c++ - 编译器在 std::move 和 deleted 复制构造函数方面的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67226687/

相关文章:

c++ - 我可以使用不完整类型列表的迭代器吗?

c++ - 转发引用和正常引用的部分排序与推导指南

java - 从 C++ 到 Java 的简单转换

c++ - 如何使用 opencv c++ 增加图像的对比度?

c++ - 自动模板参数可以传什么有限制吗?

c++ - 如何打印 n 维 C++ STL 容器?容器是数组的数组或 vector 的 vector

c++ - 如何使用 C++ Expects 运算符?

类模板的所有实例化的 C++ 簿记

c++ - `constexpr` 参数在编译时未知时不调用构造函数

c++ - 在 C++ 中使用智能指针如何帮助下面的示例