Проблема заполнения вектора построенными объектами структуры - PullRequest
0 голосов
/ 24 марта 2020

Я реализую свою версию проблемы столовых философов, используя ncurses, и столкнулся с проблемой инициализации вектора из Fork объектов.

#include <vector>
#include <mutex>
#include <ncurses.h>

...

struct Fork
{
    Fork(WINDOW *fork_window) : fork_window(fork_window) {}
    std::mutex m;
    WINDOW *fork_window;
};

std::vector<WINDOW *> fork_windows; // properly populated later
std::vector<Fork> forks;

...

for (int i = 0; i < num_of_phils; i++)
{
    forks.emplace_back(Fork(fork_windows[i]));
}

Интересно, в чем здесь моя ошибка (I ' Я не так опытен в современном C ++). Список инициализаторов в Fork неправильный или элемент std::mutex вызывает проблемы? Я успешно заполнил другой вектор подобным образом, но другая структура не имела члена std::mutex, только WINDOW * и трех ints.

Ошибка в терминале довольно длинная и говорит:

error: use of deleted function ‘Fork::Fork(Fork&&)’, 

...

note: ‘Fork::Fork(Fork&&)’ is implicitly deleted because the default definition would be ill-formed:

Впервые я вижу такую ​​ошибку, и поиск в Google также не помог, поскольку я нигде не нашел подобного случая.

1 Ответ

1 голос
/ 24 марта 2020

При существующем состоянии у вас не может быть std::vector<Fork>, потому что std::mutex не может быть ни скопирован, ни перемещен, и это неявно удаляет как конструкторы копирования, так и перемещения Fork.

. Вместо этого рассмотрите возможность использования std::vector<std::unique_ptr<Fork>> вот так:

#include <vector>
#include <mutex>
#include <memory>
#include <ncurses.h>

...

struct Fork
{
    Fork(WINDOW *fork_window) : fork_window(fork_window) {}
    std::mutex m;
    WINDOW *fork_window;
};

std::vector<WINDOW *> fork_windows; // properly populated later
std::vector<std::unique_ptr <Fork>> forks;

...

for (int i = 0; i < num_of_phils; i++)
{
    forks.emplace_back(new Fork(fork_windows[i]));
}

Если вы предпочитаете, вы можете заменить:

forks.emplace_back (new Fork (fork_windows [i]));

на:

forks.push_back (std::make_unique <Fork> (fork_windows [i]));

Это в значительной степени вопрос стиля.


Редактировать:

Альтернативный способ исправить ваш код - объявить Fork следующим образом:

struct Fork
{
    Fork(WINDOW *fork_window) : fork_window(fork_window) {}
    std::unique_ptr <std::mutex> m = std::make_unique <std::mutex> ();
    WINDOW *fork_window;
};

Сейчас Fork является подвижным (но не копируемым).

...