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

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

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

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

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,,

Другие вопросы по тегам