C++ 对于std::move和deleted copy构造函数,编译器的行为不同 #包括 结构A{}; 结构B{ B(A&&{} B(常数B&)=删除; }; 静态void func(B){} int main(){ A A; func(std::move(a)); }

C++ 对于std::move和deleted copy构造函数,编译器的行为不同 #包括 结构A{}; 结构B{ B(A&&{} B(常数B&)=删除; }; 静态void func(B){} int main(){ A A; func(std::move(a)); },c++,c++17,C++,C++17,该计划被以下机构接受: GCC自7.1起,带有-std=c++17 GCC主干(可能默认使用C++17?) 从5.0开始使用-std=c++17 MSVC是我能找到的所有版本 在C++17中,是否更改了与此相关的标准?MSVC在C++17之前接受这一点是错误的吗?MSVC是错误的。从C++17开始 这些对象被直接构造到存储中,它们将 否则将被复制/移动到。复制/移动构造函数不需要 现有或可访问: 在对象初始化中,当初始值设定项表达式是与 变量类型: 给定func(std::move(a)

该计划被以下机构接受:

  • GCC自7.1起,带有
    -std=c++17
  • GCC主干(可能默认使用C++17?)
  • 从5.0开始使用
    -std=c++17
  • MSVC是我能找到的所有版本
在C++17中,是否更改了与此相关的标准?MSVC在C++17之前接受这一点是错误的吗?

MSVC是错误的。从C++17开始

这些对象被直接构造到存储中,它们将 否则将被复制/移动到。复制/移动构造函数不需要 现有或可访问:

  • 在对象初始化中,当初始值设定项表达式是与 变量类型:
给定
func(std::move(a))
std::move(a)
首先通过
B::B(a&&)
构造一个临时
B
,然后通过
B::B(const B&)
将该临时变量作为参数复制到
func
。复制操作完全被省略,参数直接通过
B::B(a&&)
std::move(a)
构造而成


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

编译器的行为有什么不同?
std::如果我希望在这里进行构造,我不会在
B
中看到复制/移动。(被接受的语法是
func({std::move(a)})
)@Jarod42我无法得到区别,为什么
func({std::move(a)})不需要复制/移动?它是否仍然构造一个临时的
B
,然后将pass复制到
func
?我也看不出有什么区别。(但对我来说,它们都是就地构造的,所以没有复制;-)@Jarod42,正如OP所说,
func(std::move(a))无法使用编译,而
func({std::move(a)})。嗯…不知道它是否有用,但是没有大括号,函数参数是copy初始化的,而有大括号,它是copy list初始化的。这与
B=std::move(a)相同
bb={std::move(a)},其中只有后者在C++11/14中编译。