Как реализовать метод, который вызывает любой конструктор, такой как emplace_back в векторе? [Дубликат]

Вы можете приблизить sizeof(bitset<N>) как:

  1. Если внутреннее представление 32bit (например, без знака в 32-битных системах) как 4 * ((N + 31) / 32)
  2. Если внутреннее представление - 64 бит ( как unsigned long на 64-битных системах) как 8 * ((N + 63) / 64)

Кажется, что первое верно: 4 * ((3 + 31) / 32) - 4

4
задан Community 23 May 2017 в 11:44
поделиться

2 ответа

С помощью:

template <typename R, typename... Ts>
void pushNew(Ts&&... args) {
    push(new (*this) R(std::forward<Ts>(args)...));
}

Вы можете написать:

executor.PushNew<MyRunnable>("Hello", 123);

вместо

executer.push(new (executer) MyRunnable("Hello", 123));
11
ответ дан Jarod42 15 August 2018 в 18:18
поделиться
  • 1
    Хотя это и есть принятый ответ, ответ от Барри намного лучше. – Martin Bonner 7 August 2018 в 13:49

В этом есть две вещи:

template <typename R> // this don't works
void pushNew(R) {
    push(new (*this) R);
}

На первый ответ отвечает Jarod42 в том, что вы хотите сделать:

template <typename R, typename... Ts>
void pushNew(Ts&&... args) {
    push(new (*this) R(std::forward<Ts>(args)...));
}

, но что еще более важно ... new (*this) R является действительно причудливым . Похоже, вы строите R над собой! Но это не так, вы просто используете этот синтаксис для вызова своего распределителя. Это ужасно нарушает принцип наименьшего удивления. Мне потребовалось довольно много времени, чтобы понять, что происходит.

То, что вы должны, просто использует ваш распределитель напрямую:

template <typename R, typename... Ts>
void pushNew(Ts&&... args) {
    void* slot = allocateEntry(sizeof(R));
    push(new (slot) R(std::forward<Ts>(args)...));
}

Это намного легче понять.

11
ответ дан Community 15 August 2018 в 18:18
поделиться
  • 1
    должны быть приняты. Случайные навигаторы должны знать, что это тот ответ, который я предпочитаю! :) – GameDeveloper 4 October 2015 в 13:16
Другие вопросы по тегам:

Похожие вопросы: