显式对象成员函数中的移动省略:调用临时对象时是否必须省略移动?
调用临时对象的显式对象成员函数时,是否必须省略临时对象的移动?
当调用临时对象的显式对象成员函数时,显式对象参数中是否必须省略该临时对象的移动?
考虑如下示例:结构体A的移动构造函数被删除,对临时A对象调用成员函数f(this A):
struct A { A() {} A(A&&) = delete; void f(this A) {} }; int main() { A{}.f(); }
GCC接受这段代码,但Clang和MSVC均拒绝,报错信息分别为:
call to deleted constructor of 'A'
error C2280: 'A::A(A &&)': attempting to reference a deleted function
根据C23显式对象参数的规范,当调用A{}.f()时,显式对象参数的传递应当触发临时对象到值参数的拷贝省略。C标准明确规定:当实参是临时对象,且其类型与形参类型(忽略cv限定)相同时,编译器必须尝试省略拷贝或移动构造操作——即使对应的构造函数被删除或不可访问。
这里的核心问题在于,this A作为值类型的显式对象参数,实参是临时的A{},此时编译器无需调用移动构造,直接复用临时对象的内存即可。因此GCC的处理符合标准要求,而Clang和MSVC错误地尝试调用被删除的移动构造,违背了拷贝省略的规则。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

