在向量中存储 unique_ptr

Storing unique_ptr in vector

我已经在 SO 上阅读了很多关于此的主题,但到目前为止没有任何解决方案对我有用,所以我一定是做错了什么。

这个有效:

std::vector<CalendarDay*> calendarWeek;
calendarWeek.push_back(new CalendarDay(hWndParam, ctrlRc, timeParam, week * MY_CLDR_DAYS + day));

这行不通(根据 this,它应该行得通):

std::vector<std::unique_ptr<CalendarDay>> calendarWeek;
calendarWeek.push_back(std::unique_ptr<CalendarDay>(new CalendarDay(hWndParam, ctrlRc, timeParam, week * MY_CLDR_DAYS + day)));

这也不起作用(根据 this,它应该起作用):

std::vector<std::unique_ptr<CalendarDay>> calendarWeek;
std::unique_ptr<CalendarDay> item(new CalendarDay(hWndParam, ctrlRc, timeParam, week * MY_CLDR_DAYS + day));
calendarWeek.push_back(std::move(item));

这也不行:

std::vector<std::unique_ptr<CalendarDay>> calendarWeek;
std::unique_ptr<CalendarDay> item(new CalendarDay(hWndParam, ctrlRc, timeParam, week * MY_CLDR_DAYS + day));
calendarWeek.emplace_back(std::move(item));

错误总是一样的:

Error   C2280   'std::unique_ptr<CalendarDay,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function

我做错了什么?

完整代码示例:

//  DECLARED IN HEADER
std::vector<std::vector<std::unique_ptr<CalendarDay>>> calendar; // holds pointer to each day control in calendar


//  MEMBER FUNCTION
void Calendar::GenerateDays
(
      std::shared_ptr<Time> &timeParam // handles time information of displayed data
    , HWND hWndParam // handle to main window
)
{
    //  GENERATE DAY CONTROLS

    for (int week = 0; week < MY_CLDR_WEEKS; week++)
    {
        std::vector<std::unique_ptr<CalendarDay>> calendarWeek; // stores controls for one week
        for (int day = 0; day < MY_CLDR_DAYS; day++)
        {
            //  CREATE NEW CONTROL

            RECT ctrlRc // position of new control in main window
            {
                  daysOfstLeft + day * (dayWidth + dayOfst) // left border
                , daysOfstTop + week * (dayHeight + dayOfst) // top border
                , dayWidth // width
                , dayHeight // height
            };

            //  STORE DAY CONTROL IN VECTOR

            calendarWeek.reserve(sizeof(std::unique_ptr<CalendarDay>));
            calendarWeek.push_back(std::unique_ptr<CalendarDay>(new CalendarDay
            (
                  hWndParam
                , ctrlRc
                , timeParam
                , week * MY_CLDR_DAYS + day
            )));
        }
        calendar.reserve(sizeof(calendarWeek));
        calendar.push_back(calendarWeek);
    }
}

根据您的代码,问题似乎出在函数 calendar.push_back(calendarWeek) 的最后一行。它应该是 calendar.emplace_back(std::move(calendarWeek)),否则,您正在尝试复制 std::unique_ptrs 的向量,并且由于 std::unique_ptrs 没有复制构造函数,您会遇到编译错误。

该错误基本上表明正在调用包裹在唯一指针中的对象的复制构造函数。

唯一指针具有唯一所有权的语义,这意味着对象只有一个所有权,在您的情况下 CalendarDay 对象。

以下应该有效

std::vector<std::unique_ptr<CalendarDay>> calendarVec;

calendarVec.emplace_back(std::make_unique<CalendarDay>(hWndParam, ctrlRc, timeParam, week * MY_CLDR_DAYS + day);

如果您确实需要使用现有的唯一指针对象,您可以使用释放原始指针的 std::unique_ptr::release() 方法传输存储在唯一指针中的对象。所以你可以这样做:

std::unique_ptr<CalendarDay> day{std::make_unique<CalendarDay>>(hWndParam, ctrlRc, timeParam, week * MY_CLDR_DAYS + day);
std::vector<std::unique_ptr<CalendarDay>> calendarVec;
calendarVec.emplace_back(day.release());

转让对象的所有权后,对象不再安全使用。