Итерирование различных шаблонных типов
Я застрял на этом некоторое время, и у меня закончились идеи, помощь оценена!
Следующие сегменты являются примером кода, чтобы упростить.
Предположим следующее:
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)))... };
}
Есть идеи? Большое спасибо.
1 ответ
Я предполагаю, что вы только что столкнулись с ошибкой MSVC. Ошибка компиляции:
ошибка C3535: не удается вывести тип для 'auto' из списка инициализаторов
не действителен C++11 допускает вычет для auto
из списка фигурных скобок при условии, что все типы одинаковы. В твоем случае, std::map::erase
возвращает size_t
, так что это должно скомпилировать. Вот пример с вашим кодом.
Чтобы обойти это, вы можете просто явно указать тип:
size_t dummy[] = {m.erase(typeid(T))...};
Или, на всякий случай, если кто-то переходит без типов, добавьте ноль:
size_t dummy[] = {0u, m.erase(typeid(T))...};
Таким образом, в массиве всегда будет хотя бы один элемент. Более типичное использование, которое Керрек предложил в своем комментарии, будет следующим:
int dummy[] = {0, (void(m.erase(typeid(T)), 0)... };
Это будет работать независимо от выражения, которое вы замените m.erase(...)
с, так как значение (..., 0)
является 0
, void
есть ли избежать проблем с перегрузкой operator,
,