Edit: с ключевым словом final в реализациях виртуальной функции приводит к печати правильной строки, но зачем здесь ключевое слово final? Может кто-нибудь объяснить?
Я возился с различными c шаблонами, у меня довольно общие c классы D1, D2, D3, ... и все они происходят от класса A. Каждый класс имеет stati c и функции печати Dynami c, родительский класс имеет виртуальную функцию c print для Dynami c диспетчеризации. Когда я пытаюсь воспроизвести его в одном файле:
class A {
public:
virtual void printDynamic();
static void printStatic();
}
class D1 : public A {
public:
virtual void printDynamic();
static void printStatic();
}
И у меня есть следующие варианты:
std::variant<A,As...> apvar;
std::variant<A*,As*...> avar;
Я создаю оба варианта со всеми производными классами D1, D2, .. . (Я знаю повышающие указатели, я просто хочу разыменовать их типы и делать случайные вещи)
Я реализовал рекурсивные посетители для оберток, мне нужно это зафиксировать, потому что я инкапсулировал большинство функций в классе, когда я вызываю посетителя на занятия, я получаю имена «DX», «DX»; X соответствует 1.
template<class X, class Y, class... Zs>
void visit_actor(){
std::visit(
[this](auto&& value){
if constexpr(std::is_same<expr_type<decltype(value)>,expr_type<X>>::value){
value.printStaticName();
value.printDynamicName();
} else{
visit_actor<Y,Zs...>();
}
}, avar
);
}
Но если я вызываю посетителя по вариантам указателя и когда я вызываю функции: Для функции stati c я получаю: «DX» с X, соответствующим I, но когда я вызываю функцию Dynami c, я получаю имя: «Abstract A».
template<class X, class Y, class... Zs>
void visit_pointer(){
std::visit(
[this](auto&& value){
if constexpr(std::is_same<expr_type<decltype(value)>,expr_type<X>>::value){
value->printStaticName();
value->printDynamicName();
} else{
visit_pointer<Y,Zs...>();
}
}, apvar
);
}
Я пробовал прочитать об этом в документации по C ++, но пока не смог найти причину. В чем может быть причина того, что функция stati c производного класса вызывается, но вызывается виртуальная функция родителей?
Для примера Minimal Producable вам необходимо создать экземпляры классов: *
Результат:
thrud@thrud ~/wörk/test $ g++ main.cpp -std=c++17
thrud@thrud ~/wörk/test $ ./a.out
dynamic D2
y
z
static D2
dynamic D2
d
a
static D2
Segmentation fault
Итак, я думаю, что наткнулся на неопределенное поведение, но все же хотел бы знать причину.