Suppose I have a templated function that takes a generic parameter that sticks to the concept/interface of its CRTP base class like
template <typename Parser_T>
void print(Parser_T&& parser)
Now I want to iterate over a sequence of those CRTP derived instances to invoke this function. The best I came up was to use std::variant of all known sub classes, and use std::visit combined with a lambda to invoke the templated function.
Is there an easier way to do this, especially getting rid of the lambda? I don't have to store the instances homogeneous, some kind of a template trick list would be fine. But I have to able to specify the order, i.e. the instance sequence of course to invoke.
Example:
#include <iostream>
#include <array>
#include <variant>
#include <string>
template <class T>
struct parser_base
{
std::string parse()
{
return static_cast<T*>(this)->parse_impl();
}
};
struct parser_a : parser_base<parser_a>
{
std::string parse_impl() {
return "A\n";
}
};
struct parser_b : parser_base<parser_b>
{
std::string parse_impl() {
return "B\n";
}
};
template <typename Parser_T>
void print(Parser_T&& parser) {
std::cout << parser.parse();
}
int main() {
using var_t = std::variant<parser_a, parser_b>;
std::array<var_t,2> parser_list{parser_a{}, parser_b{}};
for(auto &parser: parser_list) {
std::visit([](auto &&arg) {
print(arg);
}, parser);
}
}