问题 删除函数unique_ptr


我根本不理解错误输出,我写了一个生成它的类。

UserQueues.h

#ifndef USERQUEUES_H
#define USERQUEUES_H

#include <deque>
#include <vector>
#include <memory>
#include "Job.h"

class UserQueues 
{
    public:
        typedef std::unique_ptr<Job> JobPtr;
        typedef std::deque<JobPtr> JobDeque;

    public:
        UserQueues();
        void printDeques();
        void addToDeque(JobPtr job, int queueId);

    public:
        const uint QUEUE_QTY = 3;

    private:
        std::vector<JobDeque> _jobDeques;
};

#endif

UserQueues.cpp

#include <iostream>
#include "UserQueues.h"

UserQueues::UserQueues() : 
    _jobDeques()
{
    for(unsigned int idx = 0 ; idx < QUEUE_QTY ; ++idx)
    {
        _jobDeques.push_back(JobDeque());
    }
}

void UserQueues::printDeques()
{
    for (std::size_t idx = 0; idx < _jobDeques.size(); ++idx)
    {
        std::cout << "[";

        for(std::size_t jdx = 0 ; jdx < _jobDeques[idx].size() ; ++jdx)
        {
            std::cout << _jobDeques[idx].at(jdx)->getArrivalTime();

            if(jdx != (_jobDeques[idx].size() - 1))
            {
                std::cout << ", ";
            }
        }
        std::cout << "]" << std::endl;
    } 
}

void UserQueues::addToDeque(JobPtr job, int queueId)
{
    _jobDeques[0].push_front(std::move(job));
}

输出:

09:31:34 **** Incremental Build of configuration Debug for project etsmtl-log710-lab02 ****
make all 
make: Warning: File `src/Job.d' has modification time 1.7e+04 s in the future
Building file: ../src/Job.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -I"/home/patrickz/git/etsmtl-log710-lab02/include" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Job.d" -MT"src/Job.d" -o "src/Job.o" "../src/Job.cpp"
Finished building: ../src/Job.cpp

Building file: ../src/UserQueues.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -I"/home/patrickz/git/etsmtl-log710-lab02/include" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/UserQueues.d" -MT"src/UserQueues.d" -o "src/UserQueues.o" "../src/UserQueues.cpp"
In file included from /usr/include/c++/4.7/deque:63:0,
                 from /home/patrickz/git/etsmtl-log710-lab02/include/UserQueues.h:4,
                 from ../src/UserQueues.cpp:2:
/usr/include/c++/4.7/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::unique_ptr<Job>; _Args = {const std::unique_ptr<Job, std::default_delete<Job> >&}]’:
/usr/include/c++/4.7/bits/stl_uninitialized.h:77:3:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::_Deque_iterator<std::unique_ptr<Job>, const std::unique_ptr<Job>&, const std::unique_ptr<Job>*>; _ForwardIterator = std::_Deque_iterator<std::unique_ptr<Job>, std::unique_ptr<Job>&, std::unique_ptr<Job>*>; bool _TrivialValueTypes = false]’
/usr/include/c++/4.7/bits/stl_uninitialized.h:119:41:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::_Deque_iterator<std::unique_ptr<Job>, const std::unique_ptr<Job>&, const std::unique_ptr<Job>*>; _ForwardIterator = std::_Deque_iterator<std::unique_ptr<Job>, std::unique_ptr<Job>&, std::unique_ptr<Job>*>]’
/usr/include/c++/4.7/bits/stl_uninitialized.h:260:63:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::_Deque_iterator<std::unique_ptr<Job>, const std::unique_ptr<Job>&, const std::unique_ptr<Job>*>; _ForwardIterator = std::_Deque_iterator<std::unique_ptr<Job>, std::unique_ptr<Job>&, std::unique_ptr<Job>*>; _Tp = std::unique_ptr<Job>]’
/usr/include/c++/4.7/bits/stl_deque.h:841:9:   required from ‘std::deque<_Tp, _Alloc>::deque(const std::deque<_Tp, _Alloc>&) [with _Tp = std::unique_ptr<Job>; _Alloc = std::allocator<std::unique_ptr<Job> >; std::deque<_Tp, _Alloc> = std::deque<std::unique_ptr<Job> >]’
/usr/include/c++/4.7/bits/stl_construct.h:77:7:   required from ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::deque<std::unique_ptr<Job> >; _Args = {std::deque<std::unique_ptr<Job, std::default_delete<Job> >, std::allocator<std::unique_ptr<Job, std::default_delete<Job> > > >&}]’
/usr/include/c++/4.7/bits/stl_uninitialized.h:77:3:   [ skipping 2 instantiation contexts ]
/usr/include/c++/4.7/bits/stl_uninitialized.h:260:63:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::deque<std::unique_ptr<Job> >*; _ForwardIterator = std::deque<std::unique_ptr<Job> >*; _Tp = std::deque<std::unique_ptr<Job> >]’
/usr/include/c++/4.7/bits/stl_uninitialized.h:283:69:   required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = std::deque<std::unique_ptr<Job> >*; _ForwardIterator = std::deque<std::unique_ptr<Job> >*; _Allocator = std::allocator<std::deque<std::unique_ptr<Job> > >]’
/usr/include/c++/4.7/bits/vector.tcc:410:6:   required from ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {std::deque<std::unique_ptr<Job, std::default_delete<Job> >, std::allocator<std::unique_ptr<Job, std::default_delete<Job> > > >}; _Tp = std::deque<std::unique_ptr<Job> >; _Alloc = std::allocator<std::deque<std::unique_ptr<Job> > >]’
/usr/include/c++/4.7/bits/vector.tcc:102:4:   required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::deque<std::unique_ptr<Job, std::default_delete<Job> >, std::allocator<std::unique_ptr<Job, std::default_delete<Job> > > >}; _Tp = std::deque<std::unique_ptr<Job> >; _Alloc = std::allocator<std::deque<std::unique_ptr<Job> > >]’
/usr/include/c++/4.7/bits/stl_vector.h:900:9:   required from ‘void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::deque<std::unique_ptr<Job> >; _Alloc = std::allocator<std::deque<std::unique_ptr<Job> > >; std::vector<_Tp, _Alloc>::value_type = std::deque<std::unique_ptr<Job> >]’
../src/UserQueues.cpp:9:40:   required from here
/usr/include/c++/4.7/bits/stl_construct.h:77:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Job; _Dp = std::default_delete<Job>; std::unique_ptr<_Tp, _Dp> = std::unique_ptr<Job>]’
In file included from /usr/include/c++/4.7/memory:86:0,
                 from /home/patrickz/git/etsmtl-log710-lab02/include/UserQueues.h:6,
                 from ../src/UserQueues.cpp:2:
/usr/include/c++/4.7/bits/unique_ptr.h:262:7: error: declared here
make: *** [src/UserQueues.o] Error 1

09:31:36 Build Finished (took 2s.52ms)

10477
2018-02-21 19:33


起源

这不能回答您的确切问题,但为什么不直接初始化 _jobDeques 像这样: UserQueues::UserQueues() : _jobDeques(QUEUE_QTY) 而不是使用循环? - user786653
这实际上解决了我的问题。为什么我不能使用常规循环来做到这一点超出我的意义。 - Patrick.SE


答案:


您没有明确遵循“三个规则”(或者这几天是五个?)。 GCC将尝试生成一个拷贝构造函数 UserQueues 因为你没有明确 = delete; 复制构造函数。当它这样做时,它会尝试复制你的 std::vector<JobDeque>,但因为那包含仅移动 std::unique_ptr,它将无法编译。所以,你的建设者 UserQueues 应该是这样的:

class UserQueues 
{

    public:
        explicit UserQueues();
        UserQueues(const UserQueues&) = delete;
        UserQueues& operator=(const UserQueues&) = delete;
        ~UserQueues() = default;

    [...]

};

防止编译器隐式生成复制构造函数。看到这个相关的问题,我问了两年了解更多信息 如何将unique_ptr的向量声明为类数据成员?


13
2018-02-21 20:00



应该添加这些修复我的问题?我刚试过,我得到了相同的错误日志。 - Patrick.SE
对不起,我实际上把它扔进了gcc,你是对的。这开始感觉像是一个错误 std::deque 由gcc实现,或者在代码中使用不当。不幸的是,我现在没有时间进一步研究。我尝试使用deque的列表,并使用 emplace_back 添加新的 JobQueue 到列表。它仍在调用复制构造函数 unique_ptr。这听起来不正确...... - Bret Kuhns
它现在正在运作。我添加了您的代码以及user786653建议。似乎问题来自于在构造函数中执行push_back。虽然我不知道在使用初始化列表时如何在内部完成... - Patrick.SE
@拍 这可能是相关的。似乎您需要提供至少一个移动/复制构造函数。 - François Moisan
@FrançoisMoisan是的,我忘了提到这一点。我打算试试 = default;移动ctor / assign in UserQueues,但没有时间提前。 - Bret Kuhns


您收到错误的原因是因为正在进行复制。不允许复制唯一指针,因为在实现中删除了unique_ptr复制构造函数。如果需要传递unique_ptr,可以使用 move 或使用参考。

也可以看看


0
2017-08-23 15:56