PlatformToolset和“已删除的函数”错误(C2280)

时间:2016-02-11 05:49:00

标签: c++ visual-studio c++11

最近我将MFC应用程序从VS2010升级到VS2015时,基本上对.vcxproj文件进行了两处更改:

  • ToolsVersion =“14.0”替换了<Project>
  • 下的ToolsVersion =“4.0”
  • 每个配置都添加了<PlatformToolset>v140</PlatformToolset>

用于在VS2010下编译ok的代码不再编译,但如果我反转第二个这些更改,它会编译。我真的不清楚为什么。代码 - 我无法清楚地发现问题 - 基本上是这样的:

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进行编译时没有错误。当我尝试在SomeClass::SomeUnion::SomeUnion( void )函数体中调用GetSomeStuff()的构造函数时出现错误:

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 个答案:

答案 0 :(得分: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一致性,另一些是过去导致错误codegen的错误。请参阅Breaking Changes VS 2012Breaking Changes VS 2013Breaking Changes VS 2015Breaking 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并没有令人信服的理由。有关显示2010年至2015年期间语言和库的更改的表格,请参阅Dual-use Coding Techniques for Games

     

真正最大的问题是VS 2010使用Windows 7 SDK而VS 2012-2015使用的是Windows 8 SDK,它在DirectX开发方面有一些相当大的差异。从技术上讲,您可以通过props解决方案让VS 2010使用Windows 8 SDK,但它不是官方支持组合。