Сохранение unique_ptr в векторе - PullRequest
0 голосов
/ 08 мая 2020

Я прочитал много тем об этом на 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);
    }
}

Ответы [ 2 ]

4 голосов
/ 08 мая 2020

Судя по вашему коду, похоже, что проблема связана с последней строкой функции calendar.push_back(calendarWeek). Это должно быть calendar.emplace_back(std::move(calendarWeek)), в противном случае вы пытаетесь скопировать вектор std::unique_ptr s, а поскольку std::unique_ptr s не имеет конструктора копирования, вы получаете ошибки компиляции.

0 голосов
/ 08 мая 2020

Ошибка в основном указывает на то, что вызывается конструктор копирования объекта, заключенного в уникальный указатель.

уникальный указатель имеет семантику уникального владения, что означает, что существует только одно владение объектом, в вашем случае 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());

После передачи права собственности на объект использование объекта становится небезопасным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...