在VS2015 C ++中处理`default`关键字可能存在错误

时间:2015-09-25 14:25:41

标签: c++ visual-studio-2015 language-lawyer

在测试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中没有的复制构造函数?

1 个答案:

答案 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(任何版本)调用复制构造函数

我认为VS compiiler仍然在2015年错误地使用了旧的C ++ 03标准规则(C ++ 03的8.5.3.5):

  

如果初始化表达式是rvalue,T2是类类型,和   &#34; cv1 T1&#34;与&#34; cv2 T2,&#34;是参考兼容的引用是绑定的   通过以下方式之一(选择是实现定义的):

     

- 引用绑定到rvalue(参见3.10)表示的对象或该对象中的子对象。

     

- 临时类型&#34; cv1 T2&#34;创建[sic],并调用构造函数将整个rvalue对象复制到临时对象中。该   引用绑定到临时或者子对象内   暂时的。

     

用于制作副本的构造函数应该是可调用的   该副本是否实际完成。

VS开发人员选择了第二种方式。他们为空的用户定义的构造函数({})更正了这个问题,但忘了为默认的(= default)构造函数执行此操作。

PS。 Bug on MS Connect(请投票)

相关问题