мне нужно использовать некоторый класс сегодня, который следовал этот базовый дизайн:C++ переместить семантику, где якобы не должно быть на пользу
class Task {
public:
Task() {
Handler::instance().add(this);
}
virtual void doSomething() = 0;
};
class Handler {
std::vector<Task*> vec;
//yea yea, we are locking the option to use default constructor etc
public:
static Handler& instance() {
static Handler handler;
return handler;
}
void add(Task* task) {
vec.push_back(task);
}
void handle() {
for (auto t : vec) {
t->doSomething();
}
}
};
template <class T, int SIZE>
class MyTask : public Task {
T data[SIZE];
public:
virtual void doSomething() {
// actually do something
}
};
//somewhere in the code:
Handler::instance().handle();
теперь, мой класс что-то вроде
class A {
MyTask<bool, 128> myTask;
public:
A(int i) {}
};
на пути Я хотел сделать это, имея карту, где экземпляры A являются значениями
static std::map<int, A> map = {
{42, A(1948)},
{88, A(-17)}
};
Сначала прояснить что-то - этот код n чтобы работать в встроенной системе реального времени, поэтому мне не разрешено выделять память с использованием новых по нескольким причинам.
Моя проблема заключалась в том, что фактические объекты на карте не были явным образом созданы, и поэтому они не регистрировались в классе Handler (поэтому я не получил преимущества вызовов Handler :: handle) ,
Я пробовал найти хороший способ решить эту проблему, не делая что-то уродливое, как сначала создавая массив A, а только указывать на эти объекты на карте, например.
Я раньше не использовал семантику перемещения, но я немного читал о них и думал, что это может быть мое решение.
Однако, прочитав this answer (особенно в самом первом примере), мне показалось, что я ничего не могу извлечь из использования семантики перемещения.
Я попробовал это в любом случае (сог почему, черт возьми, не ...) и сделал что-то вроде этого: вместо
static std::map<int, A> map = {
{42, std::move(A(1948))},
{88, std::move(A(-17))}
};
теперь моему удивлению, копия конструктор MyTask еще называется (я положить печать в нем для проверки), но по какой-то причине регистрация обработчиков работала хорошо, и мои экземпляры пользовались вызовами doSomething().
Я попытался более подробно прочитать о std :: move, чтобы понять, что именно там произошло, но не смог найти ответ.
может кто-нибудь объяснить это? std :: move перемещает это указатель как-нибудь? или, возможно, это только вызвало регистрация произойдет правильно как-то и не было ничего реального делать с движущейся попыткой
благодаря
редактировать:
для дальнейшего уточнения, что я спрашиваю:
Я понимаю, что использование std :: move не способствовало тому, что там делается.
Но по какой-то причине он действительно получил мои объекты на карте, чтобы получить вызов doSomething() через обработчик. Я искал эту причину
на боковой ноте, поскольку она, вероятно, относится к другому вопросу - есть ли достойный способ инициализировать карту таким образом без накладных расходов на создание каждого объекта дважды?
Этот вопрос по-прежнему не совсем ясен для меня. Ваш пример не имеет смысла - где эта 'std :: map' вступает в игру и как она каким-либо образом связана с« Handler »? Пожалуйста, создайте реальный [mcve] – AndyG
, почему это имеет значение, где карта вступает в игру? и обработчик регистрирует созданные объекты задачи – user2717954
Кроме того, если вам не разрешено выполнять выделение памяти, то вам, вероятно, не разрешено использовать использование 'std :: map' (если вы не предоставите ему специальный распределитель, который не нарушите ваши ограничения). – Hurkyl