我可以理解编译器正在下面的代码中执行复制-省略,因为在所谓的copy-initialization中,main()中没有调用复制和移动构造函数。见实例化。
#include <iostream>
struct S {
S() = default;
S(const S&) { std::cout << "copy ctor" << '\n'; }
S(S&&) { std::cout << "move ctor" << '\n'; }
};
int main() {
S s = S();
}但是,当我删除以下移动构造函数时,我不明白为什么代码不编译:
#include <iostream>
struct S {
S() = default;
S(const S&) { std::cout << "copy ctor" << '\n'; }
S(S&&) = delete;
};
int main() {
S s = S();
}我在§12.8/32 (N4140)中找不到任何可能不允许复制构造函数被使用或删除的东西,在这种情况下。这句话在第12.8/32节中引起了我的注意,这句话似乎表明,重载解决方案应该考虑副本构造函数:
如果第一个重载解析失败或没有执行,或者所选构造函数的第一个参数的类型不是对对象类型(可能是cv限定的)的rvalue引用,则将再次执行重载解析,将对象视为lvalue。
编辑
从下面T.C.的一个注释中,我了解到当要复制的对象由rvalue指定时,编译器,根据§12.8/32,并不认为复制构造函数是复制的候选函数,即使副本无论如何都会被省略。也就是说,最终结果将是使用默认构造函数构造对象s。相反,在这种情况下,标准任务(哪里?)代码格式不正确。除非我对这个计划的理解是完全错误的,那对我来说是毫无意义的。
发布于 2015-08-03 00:07:05
这与复制省略或构造函数无关;它只是过载解析。
如果我们有一对超载:
void f( T&& rv );
void f( const T& lv );然后,重载解析规则表明f( T{} )是f(T&&)的更好匹配。
复制省略可以删除一个副本或移动,但只有当代码定义良好时(即使编译器选择不实现复制省略)。您的代码没有很好的定义,因为它指定调用已删除的函数.
https://stackoverflow.com/questions/31775876
复制相似问题