locked
Issue with std::unique_ptr in a map RRS feed

  • Question

  • Hi,

    Using visual studio 2013..vc++ project.

    Getting compilation error in following scenario.(The following types fail to compile by referencing a deleted function, the copy constructor of the unique_ptr.)... Working fine with VS 2010. Failes in VS2013.

    I have a map as member inside a class.

    class myclass{

    myclass();

    ~myclass();

    private:

    std::map<int,std::unique_ptr<int>> mymap;

    }

    Any suggestion to fix the same?

    Regards,

    Adettu

    Wednesday, September 9, 2015 4:36 PM

Answers

  • This isn't __declspec(dllexport)'s fault, you get the same error if you do this:

    #include <map>
    #include <memory>
    
    class myclass
    {
        std::map<int, std::unique_ptr<int>> mymap;
    };
    
    int main()
    {
        myclass m;
        myclass m2 { m };
    }
    
    unique_ptr isn't copyable so map<int, unique_ptr<int>> and myclass aren't copyable as well. myclass should have deleted copy constructor and assignment operator to prevent the compiler from generating them when __declspec(dllexport) is used (and get saner error messages when __declspec(dllexport) isn't used).

    • Proposed as answer by Shu 2017 Thursday, September 17, 2015 11:08 AM
    • Marked as answer by Shu 2017 Monday, September 21, 2015 11:35 AM
    Thursday, September 10, 2015 11:22 AM

All replies

  • I copied the above code into a VS 2013 (Update 5) VC++ project and the code compiled without error.

    Have you installed Update 5 to your VS 2013?

    Wednesday, September 9, 2015 5:13 PM
  • Probably you are trying to copy the myclass objects. Show the situation that generates the errors.

    The next example demonstrates that you cannot copy unique_ptr:

        unique_ptr<int > u1;
        unique_ptr<int > u2;

        u1 = u2; // ERROR

    However you can move it:

        u1 = move(u2);

    The myclass can be moved too, but you have to provide the corresponding members, such as “myclass(myclass && a)” and “operator = (myclass && a)”.

    Also consider passing by reference instead of by value in case of functions.


    • Edited by Viorel_MVP Wednesday, September 9, 2015 5:20 PM
    Wednesday, September 9, 2015 5:19 PM
  • Using VS2013 Update4 
    Wednesday, September 9, 2015 5:29 PM
  • myclass not copied.

    myclass is not used anywhere. simply declared only. It showing error in the map declation statement.

    (The following types fail to compile by referencing a deleted function, the copy constructor of the unique_ptr.)..

    Wednesday, September 9, 2015 5:31 PM
  • Using VS2013 Update4 

    I suggest you apply the most recent update and try again after it is installed.
    Wednesday, September 9, 2015 5:39 PM
  • On 9/9/2015 12:36 PM, james Adettu wrote:

    Getting compilation error in following scenario.(The following types fail to compile by referencing a deleted function, the copy constructor of the unique_ptr.)... Working fine with VS 2010. Failes in VS2013.

    Compiles for me with VS2013 ( http://rextester.com/CMTY84724 ). The problem is somewhere in the code you haven't shown.


    Igor Tandetnik
    Wednesday, September 9, 2015 5:52 PM
  • Shairing the full source.. The source is part of a DLL. Visual studio 2013 update 4.

    Actually  class is exporting one.. 

    If  __declspec(dllexport) is not used then no issues..   Issue seems to be with while exporting class cases.. Any idea?

    sample.h file...

    #pragma once

    #define COMMON_API __declspec(dllexport)

    #include <map>
    #include <memory>
    #ifndef NO_WARN_MBCS_MFC_DEPRECATION
    #define NO_WARN_MBCS_MFC_DEPRECATION
    #endif
    #include <afxinet.h>

    class COMMON_API sample
    {
    public:
    sample();
    ~sample();
    std::map<int, std::unique_ptr<CFtpConnection>> mymap;

    };


    • Edited by Uralsib Thursday, September 10, 2015 8:21 AM
    Thursday, September 10, 2015 3:11 AM
  • Compiles for me with VS2013 ( http://rextester.com/CMTY84724 ). The problem is somewhere in the code you haven't shown.

    Igor Tandetnik

    Igor -

    The error the OP is seeing appears to be related to the __declspec(dllexport) - try it
    with your simple example:

    #include <iostream>
    #include <map>
    #include <memory>
    
    // class myclass{
    class __declspec(dllexport) myclass{
      myclass();
      ~myclass();
    
    private:
      std::map<int,std::unique_ptr<int>> mymap;
    };
    
    int main()
    {
        std::cout << "Hello, world!\n";
    }
    


    I see:

    Error(s):
    
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\xtree(893) : error C2280: 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function
            with
            [
                _Ty=int
            ]
            C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\memory(1486) : see declaration of 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr'
            with
            [
                _Ty=int
            ]
            This diagnostic occurred in the compiler generated function 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)'
            with
            [
                _Kty=int
    ,            _Ty=std::unique_ptr<int,std::default_delete<int>>
            ]
    
    

    - Wayne

    Thursday, September 10, 2015 10:47 AM
  • Everything I've read indicates that exporting STL classes is either not possible, has limitations or is not a good idea.  Having said that, I just read an interesting item in the MSDN blogs. See

    http://blogs.msdn.com/b/sergey_babkins_blog/archive/2015/09/08/exporting-c-classes-with-stl-members-from-dlls.aspx

    Thursday, September 10, 2015 10:55 AM
  • This isn't __declspec(dllexport)'s fault, you get the same error if you do this:

    #include <map>
    #include <memory>
    
    class myclass
    {
        std::map<int, std::unique_ptr<int>> mymap;
    };
    
    int main()
    {
        myclass m;
        myclass m2 { m };
    }
    
    unique_ptr isn't copyable so map<int, unique_ptr<int>> and myclass aren't copyable as well. myclass should have deleted copy constructor and assignment operator to prevent the compiler from generating them when __declspec(dllexport) is used (and get saner error messages when __declspec(dllexport) isn't used).

    • Proposed as answer by Shu 2017 Thursday, September 17, 2015 11:08 AM
    • Marked as answer by Shu 2017 Monday, September 21, 2015 11:35 AM
    Thursday, September 10, 2015 11:22 AM