【发布时间】:2015-07-15 12:56:29
【问题描述】:
我将对象A 的std::unique_ptr 向量作为参数传递给对象Obj 的构造函数。当我使用如下所示的std::move 语法时,这是有效的。但是,如果我将另一个对象添加到构造函数的参数列表(以下代码中的 mpq_class i),我会收到一条 错误消息,内容为
error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'
在 OS X 和
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Interface; _Dp = std::default_delete<Interface>]’
在 Linux 系统上。
在函数getVector() 中创建unique_ptr 的向量,然后传递给Obj 构造函数,并将对象添加到另一个向量并返回。
我的问题是为什么如果我使用 std::move 作为 unique_ptrs 代码会尝试调用复制构造函数,以及如何摆脱它!
产生错误的代码如下所示。
// g++ -Wall -O3 -std=c++1y -lgmpxx -lgmp
#include <vector>
#include <gmpxx.h>
#include <gmp.h>
#include <memory>
#include <iostream>
class A {
public:
A( int y ) : x(y) {}
int x;
};
class Obj {
public:
Obj( mpq_class i, std::vector<std::unique_ptr<A> > v ) : number(i), cont( std::move(v) ) {}
mpq_class number;
std::vector<std::unique_ptr<A> > cont;
};
std::vector<Obj> getVector()
{
std::vector<Obj> result;
int M = 3, N = 5;
for( int mm = 0; mm < M; mm++ )
{
mpq_class rational;
std::vector<std::unique_ptr<A> > abstractObjectsForConstructor;
for(int nn = 0; nn < N; nn++ )
{
mpq_class r(mm,nn);
rational = r;
abstractObjectsForConstructor.push_back( std::make_unique<A>(nn) );
}
result.emplace_back( rational, std::move(abstractObjectsForConstructor) );
}
return result;
}
int main()
{
std::vector<Obj> vec = getVector();
for( unsigned int ii = 0; ii < vec.size(); ii++ )
{
for( unsigned int jj = 0; jj < vec[ii].cont.size(); jj++ )
{
std::cout << vec[ii].cont[jj]->x << '\t' << std::endl;
}
}
return 0;
}
整个错误信息如下:
In file included from vector_unique.cpp:2:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:265:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:15:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:628:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1645:31: error:
call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1572:18: note:
in instantiation of function template specialization 'std::__1::allocator<std::__1::unique_ptr<A,
std::__1::default_delete<A> > >::construct<std::__1::unique_ptr<A, std::__1::default_delete<A> >,
std::__1::unique_ptr<A, std::__1::default_delete<A> > &>' requested here
{__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1453:14: note:
in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<A, std::__1::default_delete<A> > >
>::__construct<std::__1::unique_ptr<A, std::__1::default_delete<A> >, std::__1::unique_ptr<A,
std::__1::default_delete<A> > &>' requested here
{__construct(__has_construct<allocator_type, pointer, _Args...>(),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1005:25: note:
in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<A, std::__1::default_delete<A> > >
>::construct<std::__1::unique_ptr<A, std::__1::default_delete<A> >, std::__1::unique_ptr<A,
std::__1::default_delete<A> > &>' requested here
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1203:9: note:
in instantiation of function template specialization 'std::__1::vector<std::__1::unique_ptr<A,
std::__1::default_delete<A> >, std::__1::allocator<std::__1::unique_ptr<A, std::__1::default_delete<A> > >
>::__construct_at_end<std::__1::unique_ptr<A, std::__1::default_delete<A> > *>' requested here
__construct_at_end(__x.__begin_, __x.__end_);
^
vector_unique.cpp:15:8: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<A,
std::__1::default_delete<A> >, std::__1::allocator<std::__1::unique_ptr<A, std::__1::default_delete<A> > >
>::vector' requested here
class Obj {
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1572:18: note:
(skipping 2 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
{__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1535:17: note:
in instantiation of function template specialization 'std::__1::allocator_traits<std::__1::allocator<Obj>
>::construct<Obj, const Obj &>' requested here
construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1));
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:874:21: note:
in instantiation of function template specialization 'std::__1::allocator_traits<std::__1::allocator<Obj>
>::__construct_backward<Obj *>' requested here
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1621:5: note:
in instantiation of member function 'std::__1::vector<Obj, std::__1::allocator<Obj>
>::__swap_out_circular_buffer' requested here
__swap_out_circular_buffer(__v);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1639:9: note:
in instantiation of function template specialization 'std::__1::vector<Obj, std::__1::allocator<Obj>
>::__emplace_back_slow_path<__gmp_expr<mpq_t, mpq_t> &, std::__1::vector<std::__1::unique_ptr<A,
std::__1::default_delete<A> >, std::__1::allocator<std::__1::unique_ptr<A, std::__1::default_delete<A> > > > >'
requested here
__emplace_back_slow_path(_VSTD::forward<_Args>(__args)...);
^
vector_unique.cpp:40:11: note: in instantiation of function template specialization 'std::__1::vector<Obj,
std::__1::allocator<Obj> >::emplace_back<__gmp_expr<mpq_t, mpq_t> &, std::__1::vector<std::__1::unique_ptr<A,
std::__1::default_delete<A> >, std::__1::allocator<std::__1::unique_ptr<A, std::__1::default_delete<A> > > > >'
requested here
result.emplace_back( rational, std::move(abstractObjectsForConstructor) );
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2515:31: note:
copy constructor is implicitly deleted because 'unique_ptr<A, std::__1::default_delete<A> >' has a
user-declared move constructor
_LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
^
1 error generated.
【问题讨论】:
-
std::make_unique<A>( A(nn) )应该是std::make_unique<A>(nn) -
@Matt:抱歉,改了。但是,如果我评论
result.emplace_back( rational, std::move(abstractObjectsForConstructor) );,错误就会消失 - 当Obj的构造函数被调用时 -
显示整个错误信息。每个主要编译器都会列出带有错误消息的行号。告诉我们您的代码的哪一行对应于错误中的行号。
-
您确定
mpq_class是可移动的吗? (如果不是,那么Obj将不可移动) -
如果我创建一个虚拟 mpq_class,gcc 5.1.0 编译此代码不会出错。你用什么编译器?
标签: c++ c++11 constructor c++14 unique-ptr