使用std :: move将unique_ptr移到向量中

时间:2019-02-21 03:59:47

标签: c++ c++11 vector std unique-ptr

我一直试图创建一个 conda install pyspark=2.3.0 ,然后使用unique_ptr将其移动到该指针的向量中。当我尝试执行此操作时,出现了很长的编译错误。我已经阅读了有关此主题的多个问题,包括此处的“ unique_ptr的容器”部分:https://eli.thegreenplace.net/2012/06/20/c11-using-unique_ptr-with-standard-library-containers

以及以下StackOverflow问题:Why can I not push_back a unique_ptr into a vector?

这是一个不会编译的小型示例程序:

push_back()

这是程序给我的编译器错误:

// ptrtest.cpp
#include <memory>
#include <vector>

class TestObject{
public:
    TestObject(int data): data(data){}
    int getData(){return data;}
private:
    int data;
};

using namespace std;
int main (int argc, char* argv[]){
    vector<unique_ptr<TestObject> > v;
    unique_ptr<TestObject> obj = unique_ptr<TestObject>(new TestObject(5));
    v.push_back(move(obj));

    return 0;
}

我的编译器是$ clang++ ptrtest.cpp -otest In file included from ptrtest.cpp:1: /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1574:36: error: no matching constructor for initialization of 'std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >' ::new ((void*)__p) _Tp(__a0); ^ ~~~~ /Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1593:25: note: in instantiation of function template specialization 'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::construct<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > >' requested here __alloc_traits::construct(this->__alloc(), ^ ptrtest.cpp:16:4: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::push_back' requested here v.push_back(move(obj)); ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2482:3: note: candidate constructor not viable: 1st argument ('const std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >') would lose const qualifier unique_ptr(unique_ptr&); ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2498:3: note: candidate constructor not viable: no known conversion from 'const std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >' to 'std::__1::nullptr_t' for 1st argument unique_ptr(nullptr_t) : __ptr_(pointer()) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2504:12: note: candidate constructor not viable: no known conversion from 'const std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >' to 'std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >::pointer' (aka 'TestObject *') for 1st argument explicit unique_ptr(pointer __p) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2516:3: note: candidate constructor not viable: no known conversion from 'const std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >' to '__rv<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > >' for 1st argument unique_ptr(__rv<unique_ptr> __u) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2483:35: note: candidate template ignored: deduced type 'unique_ptr<...>' of 1st parameter does not match adjusted type 'const unique_ptr<...>' of argument [with _Up = TestObject, _Ep = std::__1::default_delete<TestObject>] template <class _Up, class _Ep> unique_ptr(unique_ptr<_Up, _Ep>&); ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2490:3: note: candidate constructor not viable: requires 0 arguments, but 1 was provided unique_ptr() : __ptr_(pointer()) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2535:3: note: candidate constructor not viable: requires 2 arguments, but 1 was provided unique_ptr(pointer __p, deleter_type __d) ^ In file included from ptrtest.cpp:2: /Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1580:21: error: no matching member function for call to 'construct' __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), ... ~~~~~~~~~~~~~~~~^~~~~~~~~ /Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1599:9: note: in instantiation of function template specialization 'std::__1::vector<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::__push_back_slow_path<const std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > >' requested here __push_back_slow_path(__x); ^ ptrtest.cpp:16:4: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::push_back' requested here v.push_back(move(obj)); ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note: candidate template ignored: substitution failure [with _Tp = std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, _A0 = std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >] static void construct(allocator_type&, _Tp* __p, const _A0& __a0) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note: candidate function template not viable: requires 2 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note: candidate function template not viable: requires 4 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note: candidate function template not viable: requires 5 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1677:17: error: use of undeclared identifier 'construct' construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD:... ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/vector:898:21: note: in instantiation of function template specialization 'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::__construct_backward<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > *>' requested here __alloc_traits::__construct_backward(this->__alloc(), this->__begin_... ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1582:5: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::__swap_out_circular_buffer' requested here __swap_out_circular_buffer(__v); ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1599:9: note: in instantiation of function template specialization 'std::__1::vector<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::__push_back_slow_path<const std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > >' requested here __push_back_slow_path(__x); ^ ptrtest.cpp:16:4: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, std::__1::allocator<std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > > >::push_back' requested here v.push_back(move(obj)); ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note: must qualify identifier to find this declaration in dependent base class static void construct(allocator_type&, _Tp* __p) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note: must qualify identifier to find this declaration in dependent base class static void construct(allocator_type&, _Tp* __p, const _A0& __a0) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note: must qualify identifier to find this declaration in dependent base class static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note: must qualify identifier to find this declaration in dependent base class static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1677:17: error: no matching function for call to 'construct' construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD:... ^~~~~~~~~ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note: candidate template ignored: substitution failure [with _Tp = std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, _A0 = std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >] static void construct(allocator_type&, _Tp* __p, const _A0& __a0) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note: candidate function template not viable: requires 2 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note: candidate function template not viable: requires 4 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note: candidate function template not viable: requires 5 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1677:17: error: no matching function for call to 'construct' construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD:... ^~~~~~~~~ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note: candidate template ignored: substitution failure [with _Tp = std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >, _A0 = std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >] static void construct(allocator_type&, _Tp* __p, const _A0& __a0) ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note: candidate function template not viable: requires 4 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note: candidate function template not viable: requires 5 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p, const _A0& __a0, ^ /Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note: candidate function template not viable: requires 2 arguments, but 3 were provided static void construct(allocator_type&, _Tp* __p) ^ 5 errors generated. ,并且我正在运行macOS 10.14.3。

1 个答案:

答案 0 :(得分:5)

确定要使用c ++ 11吗?

在c ++ 11之前,push_back(...)的签名为:

void push_back (const value_type& val);

因此,即使您给出一个临时值,它仍将使用复制构造函数。

在C ++ 11中,有一个重载来处理使用临时变量移动而不是复制。

无论哪种方式,您都应该考虑使用.emplace_back(...)。这是专门为处理临时对象和内联构造对象而设计的,因此没有副本。