PlatformToolset 和“已删除功能”错误 (C2280)
Posted
技术标签:
【中文标题】PlatformToolset 和“已删除功能”错误 (C2280)【英文标题】:PlatformToolset and "deleted function" error (C2280) 【发布时间】:2016-02-11 05:49:00 【问题描述】:当我最近将 MFC 应用程序从 VS2010 升级到 VS2015 时,对 .vcxproj 文件进行了两处更改:
ToolsVersion="14.0" 替换了<Project>
下的 ToolsVersion="4.0"
每个配置都添加了<PlatformToolset>v140</PlatformToolset>
用于在 VS2010 下编译正常的代码不再编译,但如果我反转这些更改中的第二个,它确实可以编译。我真的不清楚为什么。代码——我无法清楚地发现问题——本质上是这样的:
class SomeClass
union SomeUnion
struct
CPoint thisData; // MFC/ATL type - atltypes.h
char thatData[ 6 ];
;
double otherData;
;
void SetSomeStuff( const std::vector<SomeUnion> & someStuff );
void GetSomeStuff( std::vector<SomeUnion> & someStuff );
;
这很好——在 VS2015(或 VS2010)下使用或不使用 PlatformToolset
编译时都没有错误。当我尝试在 GetSomeStuff()
函数体中调用 SomeClass::SomeUnion::SomeUnion( void )
的构造函数时出现错误,如下所示:
void SomeClass::GetSomeStuff( std::vector<SomeUnion> & someStuff )
someStuff.resize( 2 ); // error C2280 depending on compiler??
我的猜测是,使用 PlatformToolset
设置为 v140
会为联合强制执行新规则(可能在 C++11 中?),这意味着某些构造函数或赋值运算符现在被强制定义为基于某些理由删除。如果有,有什么依据? this 是否像我认为的那样相关,这是由于不能简单地复制到此处的“非平凡”元素?哪个元素以及为什么?
编辑最初这个问题被过度简化并使用short thisData
而不是CPoint thisData
,因为错误消息突出显示SomeClass::SomeClass()
是罪魁祸首。
【问题讨论】:
【参考方案1】:升级您的 VC++ 项目旨在进行单向转换,尽管已经付出了一些努力来尝试使 vcxproj 文件在往返转换中更加稳健。
当您使用 Platform Toolset v140
时,您使用的是 19.0 版的 VS 2015 C++ 编译器。它是符合 C++11 的编译器,而 VS 2010(使用 v100
Platform Toolset 的 C++ 版本 16.0)是 C++0x Draft 支持版本。
VS 2015 编译器将发出许多 VS 2010 不会发出的新警告和消息,其中一些是符合 C++11 的,另一些是关于过去导致错误代码生成的错误。请参阅 Breaking Changes VS 2012、Breaking Changes VS 2013、Breaking Changes VS 2015 和 Breaking Change VS 2015 Update 1 了解自 VS 2010 以来的重大变化。VS 2012 和 VS 2013 编译器各有 4 次更新,因此您基本上跳过了 12 个 C++ 编译器版本在这里。
另一个主要区别是 VS 2015 使用 Universal CRT。
我无法重现您的问题,因为您没有提供足够的代码。以下在 VS 2015 中构建得很好。在 /W4
下,您将收到一条警告,提示您正在使用无名结构,这在技术上是一个 MSVC 扩展,但仅此而已。
#include <vector>
class SomeClass
public:
union SomeUnion
struct
short thisData;
char thatData[ 6 ];
;
double otherData;
;
void SomeClass::GetSomeStuff( std::vector<SomeUnion> & someStuff )
someStuff.resize( 2 );
;
您的复制过程中一定遗漏了一些基本问题。也就是说,VS 2015 很可能会发出 VS 2010 不会发出的错误/警告,这是设计使然。
您可以编写使用 VS 2010 - VS 2015 干净构建的代码,但它需要坚持使用 VS 2010 支持的 C++0x 语言功能和标准 C++ 库。您可以使用一些适配器让生活更轻松一些,但是对于大多数用例来说,坚持使用 VS 2010 确实没有令人信服的理由。请参阅 Dual-use Coding Techniques for Games 获取显示 2010 年至 2015 年期间语言和库变化的表格。
真正最大的问题是 VS 2010 使用 Windows 7 SDK,而 VS 2012-2015 使用 Windows 8 SDK,这有一些相当大的差异,特别是对于 DirectX 开发。从技术上讲,您可以通过props 解决方案让 VS 2010 使用 Windows 8 SDK,但这不是官方支持的组合。
【讨论】:
谢谢 - 这看起来会很有帮助。诚然,所提供的代码是一个文件的摘录,该文件在两个项目中的编译方式不同,我认为我已经做了足够的工作来添加/删除选项和代码行以隔离问题。显然不是。如果我确实隔离了问题,我会编辑/更新。 终于回到了这个问题……发现在提取问题本质的时候,我把MyClass thisData' with
short thisData'替换成了过度简化了。 MyClass
是一个 MFC/ATL CPoint
由 typedef 提供。由于错误消息将我指向联合,我错误地认为它是 POD 类型。但是如果你使用`CPoint',你将能够重现错误。
@omatai 第 9.3 节 c++11 标准说:注意:如果联合的任何非静态数据成员具有非平凡的默认构造函数([class.ctor]),则复制构造函数([class.copy])、移动构造函数 ([class.copy])、复制赋值运算符 ([class.copy])、移动赋值运算符 ([class.copy]) 或析构函数 ([class.dtor]), union 的相应成员函数必须是用户提供的,否则会为 union 隐式删除([dcl.fct.def.delete])。 — 尾注]eel.is/c++draft/class.union以上是关于PlatformToolset 和“已删除功能”错误 (C2280)的主要内容,如果未能解决你的问题,请参考以下文章
error MSB8008: 指定的平台工具集(v110)未安装或无效。请确保选择受支持的 PlatformToolset 值