简体   繁体   English

向量 <unique_ptr<A> &gt;在构造函数中-错误:调用隐式删除的拷贝构造函数

[英]vector<unique_ptr<A> > in constructor - error: call to implicitly-deleted copy constructor

I am passing a vector of std::unique_ptr of objects A as a parameter to a constructor of objects Obj . 我将对象Astd::unique_ptr向量作为参数传递给对象Obj的构造函数。 This is working when I use the std::move syntax as is shown below. 当使用如下所示的std::move语法时,此方法有效。 However, if I add another object to the constructor's parameter list (the mpq_class i in the below code) I get an error message that reads 但是,如果将另一个对象添加到构造函数的参数列表中(以下代码中的mpq_class impq_class i收到一条错误消息 ,内容为:

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'

on OS X and 在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>]’

on a linux system. 在linux系统上。

In the function getVector() the vector of unique_ptr is created, then passed to the Obj constructor and the objects are added to another vector and returned. 在函数getVector() ,创建unique_ptr的向量,然后将其传递给Obj构造函数,然后将对象添加到另一个向量中并返回。

My question is why the code tries to call a copy constructor if I use std::move for the unique_ptrs and how to get rid of it! 我的问题是,如果我将std::move用作unique_ptrs,为什么代码会尝试调用副本构造函数,以及如何摆脱它!

The code that produces the error is shown below. 产生错误的代码如下所示。

// 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;
}

The whole error message reads: 整个错误消息显示为:

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.

Culprit is mpq_class . mpq_classmpq_class With simple dummy version it compiles fine (I commented out headers for gmp) : 使用简单的虚拟版本,它可以很好地编译(我注释掉了gmp的标头):

struct mpq_class {
   mpq_class() {}
   mpq_class( int, int );
};

However, when you make that class not movable: 但是,当您使该类不可移动时:

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;}
};

Your problem comes back. 您的问题又回来了。

So issue that if mpq_class is not movable then Obj is not movable either and usage of emplace_back implicitly generates code to copy Obj in case of relocation which fails to compile because std::unique_ptr<A> is not copyable. 因此,如果mpq_class不可移动,则Obj也不可移动,并且如果mpq_class std::unique_ptr<A>无法复制,则在无法编译的重定位情况下, emplace_back使用emplace_back隐式生成用于复制Obj代码。

[wrong, see below] [错误,请参阅下文]

The problem is with the definition of the Obj constructor. 问题在于Obj构造函数的定义。 Its second argument is passed by value, which results in a copy being made. 它的第二个参数按值传递,这将导致复制。 The fact that you use std::move in the initializer list does not change this fact. 您在初始化列表中使用std :: move的事实不会更改此事实。

The remedy is to use an rvalue reference for the second argument of the Obj constructor. 补救措施是为Obj构造函数的第二个参数使用右值引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带矢量的unique_ptr:错误:调用XXX的隐式删除副本构造函数 - unique_ptr with vector: error: call to implicitly-deleted copy constructor of XXX 错误:使用auto调用unique_ptr的隐式删除的复制构造函数 - error: call to implicitly-deleted copy constructor of unique_ptr with auto 错误:调用 &#39;std::__1::unique_ptr 的隐式删除复制构造函数<A, std::__1::default_delete<A> &gt;&#39; - error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >' 使用 unique_ptr 时调用隐式删除的复制构造函数 c++ 17 - call to implicitly-deleted copy constructor while using unique_ptr c++ 17 LLVM find_if具有unique_ptr &lt;&gt;的隐式删除副本构造函数 - LLVM find_if implicitly-deleted copy constructor with unique_ptr<> 移动构造函数(错误:调用隐式删除的拷贝构造函数) - Move constructor (error: call to implicitly-deleted copy constructor) 调用RandGenerator的隐式删除的复制构造函数 - Call to implicitly-deleted copy constructor of RandGenerator 错误:调用“ Cadena”的隐式删除副本构造函数 - error: call to implicitly-deleted copy constructor of 'Cadena' 隐式删除的复制构造函数编译错误返回指针的值 - Implicitly-deleted copy constructor compile error returning value of a pointer 尝试将参数传递给方法时出现“调用隐式删除的复制构造函数”错误 - “call to implicitly-deleted copy constructor of” error when tried to pass argument to a method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM