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

Possible bug in handling the `default` keyword in VS2015 C++

在测试 VS2015 C++ 编译器时,我偶然发现了一个带有 default 关键字的奇怪错误。如果我这样做:

struct Dummy
{
    Dummy() = default;
    Dummy(const Dummy &) = delete;
};  

int main()
{
    const Dummy& ref = Dummy();
    return 0;
}

我明白了

error C2280: 'Dummy::Dummy(const Dummy &)': attempting to reference a deleted function
note: see declaration of 'Dummy::Dummy'

但是如果我使用一个空的构造函数

struct Dummy
{
    Dummy() {}
    Dummy(const Dummy &) = delete;
};

int main()
{
    const Dummy& ref = Dummy();
    return 0;
}

代码编译。 运行 带有 g++ or clang 的第一个示例不会产生错误。

为什么在 VS2015 中使用默认构造函数会尝试在 g++ 或 clang 中不使用的复制构造函数?

这绝对是 VS 2015 中的一个错误。

在 C++11 中,将 temporary 分配给 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 上编译。只有 VS(任何版本)调用复制构造函数,如果 class 构造函数定义为 = default.

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

If the initializer expression is an rvalue, with T2 a class type, and "cv1 T1" is reference-compatible with "cv2 T2," the reference is bound in one of the following ways (the choice is implementation-defined):

-- The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.

-- A temporary of type "cv1 T2" [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.

The constructor that would be used to make the copy shall be callable whether or not the copy is actually done.

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

PS。 Bug on MS Connect(请投票)