Visual Studio 2015中的返回值优化
Return value optimization in Visual Studio 2015?
在一个项目中,我使用了如下代码:
class C {
public:
C() {}
C(const C&) = delete;
};
C f() {
return C();
}
int main() {
f();
}
在我使用的每个以前的Visual c++编译器中(直到2013年),这从来都不是问题。但是当我尝试用新的Visual c++ 2015编译器编译它时,我得到以下错误:
1>c:develc++11playgroundmain.cpp(10): error C2280: 'C::C(const C &)': attempting to reference a deleted function
1> c:develc++11playgroundmain.cpp(6): note: see declaration of 'C::C'
我不确定为什么它以前工作,但我认为,由于返回值优化,默认构造函数被调用,而不是复制构造函数。
我使用的代码是合法的c++吗?如果不是,实现这段代码的正确方法是什么,而不需要为我的类C
提供复制构造函数?我当然可以使用移动构造函数但我假设代码在c++ 11之前永远都是无效的?
函数参数和返回值使用copy-initialization初始化。复制初始化要求复制构造函数是可访问的,即使它们被(N)RVO:
省略如果T是类类型,而other的类型不同,或者如果T不是类类型,但other的类型是类类型,则检查用户定义的转换序列,该序列可以从other的类型转换为T(或者如果T是类类型并且有转换函数,则转换为T派生的类型),并通过重载解析选择最佳转换序列。转换的结果(如果使用转换构造函数,则是一个右值临时值)随后用于直接初始化对象。最后一步通常被优化掉,转换的结果直接在为目标对象分配的内存中构造,但是需要适当的构造函数(move或copy)即使不使用也可以访问。
你需要遵循5原则。由于删除了复制构造函数,因此需要定义move构造函数。
C(C&&) = default;
C& operator=(C&&) = default;
With move constructor - works
没有移动构造函数-不起作用,违反了5
注意上面的站点使用gcc,甚至它不会编译,所以它不是特定于Visual Studio的,这是一个定义和预期的行为。
也许以前它成功地选择了隐式生成的移动构造函数,但在VS 2015中,隐式生成的移动构造函数被复制操作的存在所阻塞,如果我记得正确的话,这是符合标准的行为。
所以你只需要自己定义move构造函数,可能是一个=default。
- 返回值优化:显式移动还是隐式
- 使用 std::p air 进行返回值优化
- C++ 特征图3.5,特征图不使用命名返回值优化?
- 我是否正确测试了返回值优化?
- 使用std::optional时的命名返回值优化
- 找不到使保证返回值优化工作的方法
- 局部堆栈变量成员的返回值优化
- 在没有返回值优化的情况下将两个对象加在一起时,将创建多少个临时对象
- 为什么三元运算符阻止返回值优化
- 实现move构造函数如何影响返回值优化
- 我如何确定将进行返回值优化
- 返回值优化并复制C中的ELINION
- 为什么我在此代码中没有得到返回值优化?
- 了解工厂方法和静态变量赋值的返回值优化 (Visual Studio)
- 返回值优化是否需要声明一个复制构造函数
- 从具有移动语义或返回值优化的函数返回值,但不返回复制构造函数
- RVO(返回值优化)无法解释这个谜团
- 元组/领带的返回值优化
- 无法禁用 std::string 的返回值优化
- 返回值优化和副作用