全部,当我使用初始值设定项列表格式实例化小部件数组时,指向成员变量小部件实例的裸指针会编译,但是更改为std::unique_ptr gcc后,会出现有关已删除函数的编译错误。$ uname -aLinux .. 3.5.0-21-generiC#32-Ubuntu SMP Tue Dec 11 11:11:59 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux$ g++-版本g++(Ubuntu/Linaro 4.7.2-5ubuntu1)4.7.2此代码给出以下编译器错误:#include <stdlib.h>#include <memory>class Widget{public: Widget() {}};class W1 : public Widget{public: W1() {}};class W2 : public Widget{public: W2() {}};class WFactory{public: WFactory(const int i) : _w(new W1()) {} WFactory(const char* s) : _w(new W2()) {} ~WFactory() { _w.reset(nullptr); } // ~WFactory() { delete _w; } <--- for naked ptrprivate: // NOTE: does not compile std::unique_ptr<Widget> _w; // NOTE: does compile // Widget* _w;};int main(){ std::unique_ptr<Widget> a(new W1()); // <--- compiles fine WFactory wf[] { 4, "msg" }; // <--- compiler error using unique_ptr<>}错误:$ g++ -o unique_ptr -std=c++11 -Wall unique_ptr.cppunique_ptr.cpp: In function ‘int main()’:unique_ptr.cpp:36:30: error: use of deleted function ‘WFactory::WFactory(const WFactory&)’unique_ptr.cpp:22:7: note: ‘WFactory::WFactory(const WFactory&)’ is implicitly deleted because the default definition would be ill-formed:unique_ptr.cpp:22:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Widget; _Dp = std::default_delete<Widget>; std::unique_ptr<_Tp, _Dp> = std::unique_ptr<Widget>]’In file included from /usr/include/c++/4.7/memory:86:0, from unique_ptr.cpp:2:/usr/include/c++/4.7/bits/unique_ptr.h:262:7: error: declared hereunique_ptr.cpp:36:30: error: use of deleted function ‘WFactory::WFactory(const WFactory&)’unique_ptr.cpp:36:14: warning: unused variable ‘wf’ [-Wunused-variable]我不知所措:幕后的机制导致fcxn被删除;或更简单地说,为什么与裸ptr相比,std::unique_ptr 的表达似乎受到限制。我的问题是:试点错误? 编译器错误? 是否可以使我想要的代码在不做任何更改的情况下工作? 谢谢你。 编辑1 根据您的回答,我非常感谢,我可以对WFactory进行以下更改:(标记为不道德代码)class WFactory{public: WFactory(const WFactory& wf) { (const_cast<WFactory&>(wf)).moveto(_w); } WFactory(const int i) : _w(new W1()) {} WFactory(const char* s) : _w(new W2()) {} ~WFactory() { _w.reset(nullptr); } void moveto(std::unique_ptr<Widget>& w) { w = std::move(_w); }private: std::unique_ptr<Widget> _w;};现在该程序可以编译并运行。我很高兴看到标准人员编写规范是有原因的,因此我将结果作为对我手头案例的真诚专项发布,我真的很想强调ptr的独特性。 编辑2 根据乔纳森的答复,以下代码不会隐藏隐式移动ctor:class WFactory{public: WFactory(const int i) : _w(new W1()) {} WFactory(const char* s) : _w(new W2()) {}private: std::unique_ptr<Widget> _w;};请注意,根本没有~WFactory() {..}。也许有问题,但是我发现在Main()中对wf []使用c++ 11风格的迭代会带来no-copy-ctor-for-WFactory错误。那是:int Main().. WFactory wf[] { 4, "msg" }; for ( WFactory iwf : wf ) <---- compiler error again // .. for (unsigned i = 0; i < 2; ++i) <--- gcc happy wf[i] // ..}我猜想新的c++ 11样式的迭代正在执行对象复制是不言而喻的。 最佳答案 根据C++ 11标准的8.5.1/2段: When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer listare taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause. [...]然后,对于每个元素,复制初始化都涉及创建目标类型的临时对象,然后将该临时类型用于复制构造数组中的元素。但是,您的类包含一个成员,该成员的类型是unique_ptr的实例,该实例是不可复制的。这也使您的类(class)不可复制。而且,尽管unique_ptr是可移动的,但您的类却不可移动,因为存在明确定义的析构函数可以抑制编译器隐式生成move构造函数。如果不是这种情况(例如,如果您为类明确定义了move构造函数),则可以进行复制初始化(请参见8.5/15)。尝试如下更改WFactory的定义,以了解:class WFactory{public: WFactory(const int i) : _w(new W1()) {} WFactory(const char* s) : _w(new W2()) {} WFactory(WFactory&& f) : _w(std::move(f._w)) {} ~WFactory() { _w.reset(nullptr); }private: std::unique_ptr<Widget> _w;};int main(){ std::unique_ptr<Widget> a(new W1()); WFactory wf[] { 4, "msg" }; // OK}关于c++ - std::unique_ptr删除的函数,initializer_list-驱动分配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15032501/
10-11 18:23