c++ - std::unique_ptr 在 GCC 中工作,但不会在 Visual Studio 中编译

标签 c++ gcc visual-studio-2012

<分区>

我花了一段时间,但我终于构建了一个最小的示例来说明我遇到的问题。

#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 愉快地编译了它。它还编译了真正的应用程序,完美运行。

Visual Studio 2012 坚持此代码不正确,在 vc\include\xmemory0 的第 606 行给我错误 C2248。如果我浏览了几英里的编译器输出,我会发现错误的真正源是上例中的第 11 行。 (定义 Things. 的行)VS 也拒绝编译我的真实应用程序,出现同样的错误。

那么,这段代码是否正确?如果它不正确,那么为什么 GCC 会接受它呢?以及如何使其正确?如果它是正确的,那为什么 VS 不编译它呢?有什么方法可以无条件地强制 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 ==========

最佳答案

你的问题不是std::unique_ptr而是std::vector

您的编译器附带一个旧版本的 std::vector,它要求元素类型是可复制的。

按值返回 (return b;) 应该调用 vector 的移动,但你的 std::vector 没有实现移动。

std::unique_ptr 可移动但不可复制,因此它不满足在 std::vector 中使用的 C++11 之前的要求。 .. 仍然适用于 VC++ 2012 的要求。

您最好的选择是使用更新的编译器和标准库。一种支持 std::vector 上的移动语义。

否则,您可能会通过消除 std::vector 的拷贝来取得一些进展,例如,通过让 MakeBox 填充输出参数而不是返回新对象.

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

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

关于c++ - std::unique_ptr 在 GCC 中工作,但不会在 Visual Studio 中编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52839298/

相关文章:

c - 为什么这段代码会触发 gcc 的 "maybe uninitialized"警告?

c++ - 测试 Visual Studio 2012 控制台应用程序的输入/输出

visual-studio-2012 - 项目创建失败(vs2012中的InstallShield)

使用 gcc 编译的代码不会在 visual studio 2012 中编译

c++ - OpenCV--程序停止运行@图像关键点检测步骤

c++ - 在 C++ 中分配内存而不初始化它

c++ - 从设备上下文或 gdiplus (GDI+) 中的图形对象获取图像/位图

C++ 判断一个变量是否被设置

python - py-bcrypt 安装在 win 7 64 位 python 上

c++ - 默认模板类参数混淆了 g++?