首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >vector<unique_ptr<A> > in构造函数-错误:调用隐式删除的复制构造函数

vector<unique_ptr<A> > in构造函数-错误:调用隐式删除的复制构造函数
EN

Stack Overflow用户
提问于 2015-07-15 12:56:29
回答 2查看 4.9K关注 0票数 2

我将对象的std::unique_ptr向量A作为参数传递给对象Obj的构造函数。当我使用std::move语法时,这是可行的,如下所示。但是,如果我将另一个对象添加到构造函数的参数列表(下面代码中的mpq_class i )中,则会得到一个错误消息,该消息将读取

代码语言:javascript
运行
复制
error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'

在OS和

代码语言:javascript
运行
复制
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构造函数,并将对象添加到另一个向量并返回。

我的问题是,如果我为unique_ptrs使用std::move,为什么代码试图调用一个复制构造函数,以及如何消除它!

生成错误的代码如下所示。

代码语言:javascript
运行
复制
// 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;
}

整个错误消息如下:

代码语言:javascript
运行
复制
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.
EN

回答 2

Stack Overflow用户

发布于 2015-07-15 13:34:05

罪魁祸首是mpq_class。使用简单的虚拟版本,它编译得很好(我注释掉了gmp的标头):

代码语言:javascript
运行
复制
struct mpq_class {
   mpq_class() {}
   mpq_class( int, int );
};

然而,当你使这类课程不可移动时:

代码语言:javascript
运行
复制
struct mpq_class {
   mpq_class() {}
   mpq_class( int, int );
   mpq_class( const mpq_class & ) {}
   mpq_class( mpq_class && ) = delete;

   mpq_class &operator=( const mpq_class & ) {return *this;}
};

你的问题回来了。

因此,如果mpq_class不是可移动的,那么Obj也不能移动,emplace_back的使用会隐式地生成代码,在重新定位的情况下复制Obj,因为std::unique_ptr<A>是不可复制的,所以无法编译。

票数 9
EN

Stack Overflow用户

发布于 2015-07-15 13:22:32

错,见下文

问题在于Obj构造函数的定义。它的第二个参数是通过值传递的,这将导致复制。在初始化程序列表中使用std::move并不会改变这一事实。

补救方法是对Obj构造函数的第二个参数使用rvalue引用。

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31431057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档