【问题标题】:Possible bug in handling the `default` keyword in VS2015 C++在 VS2015 C++ 中处理 `default` 关键字的可能错误
【发布时间】:2015-12-23 10:00:43
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

这绝对是 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(任何版本)调用复制构造函数。

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

如果初始化表达式是一个右值,T2 是一个类类型,并且 “cv1 T1”与“cv2 T2”引用兼容,引用被绑定 通过以下方式之一(选择由实现定义):

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

-- 创建一个“cv1 T2”[sic] 类型的临时对象,并调用构造函数将整个右值对象复制到临时对象中。这 引用绑定到临时对象或对象内的子对象 临时的。

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

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

PS。 Bug on MS Connect(请投票)

【讨论】:

  • 在 VS Pro 2017 中仍然遇到这个错误
猜你喜欢
  • 2013-10-14
  • 2014-12-13
  • 2010-12-16
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多