我可以理解编译器在下面的代码中进行了复制省略,因为在所谓的copy-initialization
done in中没有调用复制和移动构造函数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 限定的),则再次执行重载决议,将对象视为左值。
编辑
从下面TC的评论之一,我了解到,当要复制的对象由右值指定时,根据 §12.8/32,编译器不会将复制构造函数视为复制的候选者,甚至尽管无论如何都会忽略副本。也就是说,最终结果将是s
使用默认构造函数构造对象。相反,在这种情况下,标准要求(在哪里??)代码格式错误。除非我对这个方案的理解完全错误,否则这对我来说没有任何意义。