Итерирование различных шаблонных типов

Я застрял на этом некоторое время, и у меня закончились идеи, помощь оценена!

Следующие сегменты являются примером кода, чтобы упростить.

Предположим следующее:

class Base;
class DerivedA : public Base;
class DerivedB : public Base;

и это:

class Manager {
public:
std::map<std::type_index, Base*> container;

template<typename ...T>
void remove() {
// Iterate through templates somehow and...
container.erase(typeid(T));
}
}

По сути, я храню в контейнере уникальные экземпляры производных классов, используя в качестве ключа std :: type_index. Позвольте мне сделать что-то вроде:

manager.remove<DerivedA>();

С учетом сказанного я хотел бы иметь возможность делать одно и то же, но разрешить нескольким шаблонам напрямую удалять сразу несколько экземпляров, как таковые:

manager.remove<DerivedA, DerivedB>()

Я знаю, что можно перебирать вариационные шаблоны, как описано Вот, но я продолжаю получать ошибки компиляции …

ошибка C2440: «инициализация»: невозможно преобразовать из «списка инициализаторов» в «std :: initializer_list»

ошибка C3535: не удается вывести тип для ‘auto’ из списка инициализаторов

…когда я пытаюсь запустить этот код:

template<typename ...T>
void remove() {
// Iterate through templates somehow and...
auto list = {(container.erase(typeid(T)))... };
}

Есть идеи?
Большое спасибо.

6

Решение

Я предполагаю, что вы только что столкнулись с ошибкой MSVC. Ошибка компиляции:

ошибка C3535: не удается вывести тип для ‘auto’ из списка инициализаторов

не действителен C ++ 11 допускает вычет для auto из приготовился-INIT-лист, до тех пор, пока все типы одинаковы. В твоем случае, std::map::erase возвращает size_t, так что должен скомпилировать. Вот Это пример с вашим кодом.

Чтобы обойти это, вы можете просто явно указать тип:

size_t dummy[] = {m.erase(typeid(T))...};

Или, на всякий случай, если кто-то переходит без типов, добавьте ноль:

size_t dummy[] = {0u, m.erase(typeid(T))...};

Таким образом, в массиве всегда будет хотя бы один элемент. Более типичное использование, которое Kerrek предложенный в его комментарии, будет следующим:

int dummy[] = {0, (void(m.erase(typeid(T)), 0)... };

Это будет работать независимо от выражения, которое вы замените m.erase(...) с, так как значение (..., 0) является 0, void есть ли избежать проблем с перегрузкой operator,,

2

Другие решения


По вопросам рекламы [email protected]