Получение базового класса из antlrcpp :: Any

В настоящее время я портирую некоторый код из версии CT ANTLR4 на цель C ++, и в настоящее время я сталкиваюсь с некоторыми проблемами. Я построил свой AST в C # так, чтобы создать базовый класс (назовем его Base) и производные классы (назовем его Derived) с виртуальными функциями, которые я могу использовать для реализации указанных классов.

Однако, пытаясь преобразовать этот код в C ++, я продолжаю получать исключения bad_cast
Я сузил его до antlrcpp :: Any, который неправильно переводит производный класс в его базовый класс. Например:

class Base {
public:
virtual std::string ToString() const { return "Base\n"; }
};

class Derived : public Base {
public:
std::string ToString() const override { return "Derived\n"; }
};

int main() {
Derived value;
std::cout << value.ToString(); //Obviously prints out Derived
Base& base_value = value;
std::cout << base_value.ToString(); //Still works exactly as expected and prints Derived

auto any = antlrcpp::Any(value);
auto derived = any.as<Base>(); //internally uses a dynamic_cast and throws a bad_cast
std::cout << derived.ToString(); //never gets to here
}

Первоначально я думал, что это может быть, потому что он работал только с указателями, однако

auto any = antlrcpp::Any(new Derived());
std::cout << any.as<Base*>()->ToString(); //throws bad_cast

Я изменил dynamic_cast в static_cast внутри заголовка, и он будет разыгрываться, однако он печатает «Base». А прямое приведение в стиле C вызывает сбой при доступе к любому элементу данных.

Как именно я использую antlrcpp::Any получить базовый класс? Есть ли что-то очевидное, что мне не хватает?

И если это невозможно, как именно я могу обойти это? Есть метод .is (), однако во многих случаях проверка на возвращаемое значение посетителя определенного типа просто неосуществима (например, с выражениями может быть 30-40 операторов).

2

Решение

antlrcpp::any класс не предназначен для такого сценария. Это не универсальная реализация варианта.

Если вам нужно, вы должны подумать о собственной реализации Variant, использующей объединение для различных типов и т. Д., Которая не работает с стиранием типов.

Уникальные указатели, вероятно, не очень хорошая идея в этом контексте в целом, так как они не поддерживают семантику копирования (и вам это понадобится здесь). Для оценки с посетителями лучше пойти с shared_ptr вместо.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]