简体   繁体   中英

PlatformToolset and “deleted function” error (C2280)

When I upgraded an MFC application from VS2010 to VS2015 recently, essentially two changes were made to the .vcxproj file:

  • ToolsVersion="14.0" replaced ToolsVersion="4.0" under <Project>
  • Each configuration had <PlatformToolset>v140</PlatformToolset> added to it

Code that used to compile ok under VS2010 no longer compiles, although it does compile if I reverse the second of these changes. I'm really not clear why. The code -- in which I can't clearly spot a problem -- is essentially this:

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 );
};

This much is fine -- no errors when compiled with or without PlatformToolset under VS2015 (or under VS2010). The error comes when I try to invoke a constructor for SomeClass::SomeUnion::SomeUnion( void ) in the GetSomeStuff() function body with something like this:

void SomeClass::GetSomeStuff( std::vector<SomeUnion> & someStuff )
{
    someStuff.resize( 2 );  // error C2280 depending on compiler??
}

My guess is that using PlatformToolset set to v140 enforces new rules for unions (possibly in C++11?) that mean that some constructor or assignment operator is now mandatorily defined as deleted on some grounds. If so, what grounds? Is this as relevant as I think it is due to a "non-trivial" element that cannot simply be copied here? Which element and why?

EDIT Originally this question was over-simplified and used short thisData rather than CPoint thisData due to the error messages highlighting SomeClass::SomeClass() as the culprit.

Upgrading your VC++ projects is intended to be a one-way forward conversion, although some effort has been put into trying to make the vcxproj files survive a round-trip conversion more robustly.

When you use Platform Toolset v140 you are using the VS 2015 C++ compiler which is version 19.0. It is a C++11 conforming compiler, while VS 2010 (C++ version 16.0 using v100 Platform Toolset) was a C++0x Draft supporting version.

The VS 2015 compiler will emit a number of new warnings and messages that VS 2010 would not, some of which are C++11 conformance and others which are errors about things that used to result in bad codegen. See Breaking Changes VS 2012 , Breaking Changes VS 2013 , Breaking Changes VS 2015 , and Breaking Change VS 2015 Update 1 to see breaking changes since VS 2010. There were also 4 updates each to VS 2012 and VS 2013 compilers, so you are basically jumping 12 releases of the C++ compiler here.

Another major difference is that VS 2015 uses the Universal CRT .

I'm unable to repro your issue because you haven't provided enough code. The following builds just fine with VS 2015. Under /W4 you will get a warning that you are using a nameless struct which is technically a MSVC extension, but that's it.

#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 );
    }
};

You must be missing some essential issue in your repro. That said, it is quite likely that VS 2015 will emit errors/warnings that VS 2010 would not, and that's by design.

You can write code that builds cleanly with VS 2010 - VS 2015, but it requires sticking with the C++0x language features and Standard C++ Library supported by VS 2010. You can use a few adapters to make life a little easier, but there's really no compelling reason to stick with VS 2010 for most use cases. See Dual-use Coding Techniques for Games for a tables showing the changes to the language and libraries between 2010 - 2015.

Really the biggest issue is that VS 2010 uses the Windows 7 SDK while VS 2012-2015 uses the Windows 8 SDK which has some pretty major differences particularly for DirectX development. You can technically get VS 2010 to use the Windows 8 SDK via a props solution, but it's not an officially support combination.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM