2015-09-25 41 views
18

在测试VS2015 C++编译器时,我偶然发现了一个关于default关键字的奇怪错误。如果我做的:在处理VS2015中的`default`关键字时可能存在的错误C++

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

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

我得到

错误C2280: '假人::虚拟(常量假&)':试图引用删除的功能
注:看到虚拟的”的声明: :假”

但是,如果我用一个空的构造

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

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

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

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

+0

你从'const dummy&r2 {Dummy()};'得到了什么? –

+0

相关:[复制/移动elision与显式删除的复制/移动构造函数](http:// stackoverflow。com/questions/20589622) –

+0

请参阅http://stackoverflow.com/questions/31264984/c-compiler-error-c2280-attempting-to-reference-a-deleted-function-in-visual –

回答

9

这无疑是在2015年VS

在C++ 11的一个bug,临时分配到const引用不能调用拷贝构造函数,但2015年VS做。

您可以

#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年,海湾合作委员会和铛编译检查。如果类构造函数定义为= default,则只有VS(任何版本)调用复制构造函数。

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

如果初始化表达式是一个rvalue,与T2一类类型,和 “CV1 T1”是参考兼容“CV2 T2”的引用绑定以下列方式之一 (选择是实现定义的):

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

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

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

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

PS。 Bug on MS Connect(请投票)

+0

S.T.L.的回答:https://twitter.com/StephanTLavavej/status/648949525684465664 – vladon

相关问题