Я не уверен насчет названия вопроса, но в основном мне интересно, как создать функцию, похожую на посетителя, которая может работать с определенными типами в коллекции, которая правильно использует вывод типов.
Например, коллекция содержит объекты, которые наследуются от одного базового класса (Base
). Некоторые операции применяются только к определенным дочерним классам (например, FooBar
наследуется от Base
).
Одна реализация может быть
template<class T, class F>
void visit(F f)
{
for (auto c : the_collection) {
if (auto t = dynamic_cast<T*>(c)) {
f(t);
}
}
}
Проблема здесь в том, что при вызове такой функции необходимо будет дважды указать тип класса FooBar
:
visit<FooBar>([](FooBar* f) { f->some_method(); });
Я хотел бы использовать вывод типа, поэтому я могу просто написать visit([](FooBar* f) ...
, но не могу получить правильный шаблон.
Например:
template<class T>
using Visitor = std::function<void(T*)>;
template<class T>
void visit(const Visitor<T>& f)
{
for (auto c : the_collection)
if (auto t = dynamic_cast<T*>(c))
f(t);
}
работает с visit<FooBar>([](FooBar*) ...
, но не с visit([](FooBar*) ...
.
не найдена соответствующая перегруженная функция
void visit (const std :: function &) ': не удалось вывести аргумент шаблона для' const std :: function & 'from' {.... } ::
Можно ли определить шаблон, который может выводить типы таким образом, или спецификация языка не позволяет это сделать?