代码之家  ›  专栏  ›  技术社区  ›  MathematicalOrchid

unique的ptr在GCC中工作,但不会在visualstudio中编译[duplicate]

  •  2
  • MathematicalOrchid  · 技术社区  · 6 年前

    这花了我一段时间,但我终于建立了一个最小的例子来说明我的问题。

    #include <memory>
    #include <vector>
    
    class Thing
    {
    };
    
    class Box
    {
    public:
      std::vector<std::unique_ptr<Thing>> Things;
      static Box MakeBox() {Box b; return b;}
    };
    

    我真正的程序显然比这个复杂得多。

    GCC 4.8.3对此进行了编译。它还编译了真实的应用程序,效果非常好。

    坚持 vc\include\xmemory0 . 如果我涉过几英里的编译器输出,我会发现 错误的来源是上例中的第11行(定义 Things. 拒绝 编译我真正的应用程序,同样的错误。

    那么,这个代码对不对?如果它是不正确的,那么为什么GCC会接受它呢?我该怎么纠正呢?如果它 正确,那么为什么VS不编译它呢?有什么办法我可以无条件地 去编译我的程序?


    VS输出:

    1>------ Build started: Project: TestUniquePtr, Configuration: Debug Win32 ------
    1>  Main.cpp
    1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(606): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
    1>          with
    1>          [
    1>              _Ty=Thing
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
    1>          with
    1>          [
    1>              _Ty=Thing
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
    1>          with
    1>          [
    1>              _Ty=std::unique_ptr<Thing>
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled
    1>          with
    1>          [
    1>              _Ty=std::unique_ptr<Thing>
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
    1>          with
    1>          [
    1>              _Ty=std::unique_ptr<Thing>
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector(655) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled
    1>          with
    1>          [
    1>              _Ty=std::allocator<std::unique_ptr<Thing>>
    1>          ]
    1>          d:\projects\c++\testuniqueptr\testuniqueptr\main.cpp(11) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
    1>          with
    1>          [
    1>              _Ty=std::unique_ptr<Thing>
    1>          ]
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    
    2 回复  |  直到 6 年前
        1
  •  4
  •   Ben Voigt    6 年前

    你的问题不是 std::unique_ptr 但是 std::vector .

    您的编译器附带了旧版本的 标准::向量

    按值返回( return b; 不执行移动。

    标准::唯一\u ptr 是可移动但不可复制的,因此它不满足前C ++ 11在使用中的要求。 标准::向量 ... 仍然适用于VC++2012的要求。

    标准::向量 .

    否则,通过删除 标准::向量 MakeBox 填写输出参数,而不是返回新对象。

    static void MakeBox(Box& b) { /* fill Things in b provided by caller */ }
    

    不过,这可能是徒劳的,因为每当向量需要增长时,它必须将现有元素重新定位到新的存储中,并且在不完全的移动支持下,它将尝试复制这些元素。

        2
  •  3
  •   Peter Ruderman    6 年前

    问题是Box没有move构造函数,因此返回一个Box需要有一个copy构造函数(因为unique\u ptr不可复制,所以不能)。您只需为Box定义一个移动构造函数:

    Box::Box(Box&& other)
      : Things(std::move(other.Things))
    {
    }