在测试VS2015 C ++编译器时,我偶然发现了一个default
关键字的奇怪错误。如果我这样做:
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
我得到了
错误C2280:'Dummy :: Dummy(const Dummy&)':尝试引用已删除的功能
注意:请参阅'Dummy :: Dummy'的声明
但是如果我使用空构造函数
struct Dummy
{
Dummy() {}
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
代码编译。使用g++或clang运行第一个示例不会产生错误。
为什么在VS2015中使用默认构造函数尝试使用g ++或clang中没有的复制构造函数?
答案 0 :(得分:10)
这绝对是VS 2015中的一个错误。
在C ++ 11中,为const引用赋值临时不能调用复制构造函数,但VS 2015会这样做。
您可以使用
进行检查#include <iostream>
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) { std::cout << "copy ctor" << std::endl; }
void test() const { std::cout << "test" << std::endl; }
};
int main()
{
const Dummy& ref = Dummy();
ref.test();
return 0;
}
在VS 2013,2015,gcc和clang上编译。如果类构造函数定义为= default
。
我认为VS compiiler仍然在2015年错误地使用了旧的C ++ 03标准规则(C ++ 03的8.5.3.5):
VS开发人员选择了第二种方式。他们为空的用户定义的构造函数(如果初始化表达式是rvalue,T2是类类型,和 &#34; cv1 T1&#34;与&#34; cv2 T2,&#34;是参考兼容的引用是绑定的 通过以下方式之一(选择是实现定义的):
- 引用绑定到rvalue(参见3.10)表示的对象或该对象中的子对象。
- 临时类型&#34; cv1 T2&#34;创建[sic],并调用构造函数将整个rvalue对象复制到临时对象中。该 引用绑定到临时或者子对象内 暂时的。
用于制作副本的构造函数应该是可调用的 该副本是否实际完成。
{}
)更正了这个问题,但忘了为默认的(= default
)构造函数执行此操作。
PS。 Bug on MS Connect(请投票)