Я провел последние часы, пытаясь найти элегантное решение, но не смог.
Описание: я хотел бы иметь реализацию по умолчанию для функтора посетителя в классе visitor_base_all, а затем каждый из производных классов, например, visitor_override, определял бы метод именно для того, что ему нужно. Я понимаю, что это не работает, потому что оператор() не передается производным классам (из-за того, что С++ не перегружает области видимости, что достаточно справедливо), поэтому вопрос в том, как это сделать? Я думал сделать это с перегруженными лямбда-выражениями или иметь переключатель в виртуальном методе базового класса, а затем каждый производный класс перегружает только виртуальные методы, вызываемые в этом переключателе.
Что касается лямбд, я не уверен, как это сделать. Я уже читал следующее: pablo_arias arne-mertz и stack_overflow_question, но я все еще немного смущен тем, что было бы правильным правильным путем вперед.
Спасибо за ваше время
Короткий вопрос: Правильный способ С++ 17 для компиляции/работы ниже. Каков правильный способ обобщить его для большого количества производных типов в вариантах и производных классах?
(Добавить комментарии-редактировать) Моя проблема более обобщена для большого количества классов и гораздо большего количества типов, поэтому, если возможно, я бы предпочел как-то шаблонировать/обобщать ее. Ниже приведен пример только с 1 производным классом, но как правильно иметь 10 классов? (Я бы не хотел объявлять использование в каждом из них, если этого можно избежать).
#include <variant>
struct A{};
struct B{};
struct C{};
using type_x = std::variant<A,B,C>;
class base_class
{
protected:
struct visitor_base_all
{
void operator()(const A& a){std::cout<<"A_base" << std::endl;}
void operator()(const B& b){std::cout<<"B_base" << std::endl;}
void operator()(const C& c){std::cout<<"C_base" << std::endl;}
};
virtual void run(type_x evt){return std::visit(visitor_base_all{}, evt);}
};
class derived_class :public base_class
{
struct visitor_override : public visitor_base_all
{
void operator()(const C& c){};
};
virtual void run(type_x evt){return std::visit(visitor_override{}, evt);}
};
using visitor_base_all::operator();
внутри visitor_override должно помочь. - person n. 1.8e9-where's-my-share m.   schedule 29.10.2019using
является решением в обоих случаях, проблема OP заключается не в нескольких базовых классах, а в сокрытии методов-членов ... Не в более подходящих дубликатах IMO. - person Jarod42   schedule 29.10.2019using
, чтобы ввести другие имена. Тот факт, что это дело конкретно о посетителях, значения не имеет. - person Barry   schedule 29.10.2019void operator()
виртуальным и просто переопределить то, что вам нужно. Вот как обычно работает шаблон посетителя. Если вы обнаружите, что вам не нужно, чтобы он был виртуальным, вы, вероятно, неправильно используете шаблон. - person n. 1.8e9-where's-my-share m.   schedule 29.10.2019operator()
дляA
, другой дляB
и последний дляC
, или он просто задан по умолчанию или предоставлен? - person Jarod42   schedule 29.10.2019