현재 C# 버전의 ANTLR4에서 C++ 타겟으로 일부 코드를 이식하고 있으며 현재 일부 문제가 있습니다. 내가 C#에서 AST를 작성한 방법은 기본 클래스 (Base라고 부름)와 파생 클래스 (파생 클래스라고 함)를 생성하고 클래스를 구현하는 데 사용할 수있는 가상 함수를 작성하는 것이 었습니다.antlrcpp :: Any에서 Base 클래스 가져 오기
그러나이 코드를 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
}
그러나 그것을, 나는 처음에 그것은 단지 포인터와 함께 일하기 때문에 내가 헤더 내부 static_cast
에 dynamic_cast
을 변경하지만, 어쩌면
auto any = antlrcpp::Any(new Derived());
std::cout << any.as<Base*>()->ToString(); //throws bad_cast
라고 생각하고 그것을 던져 것 "Base"를 출력합니다. 또한 C 스타일 캐스팅은 데이터 멤버가 액세스 할 때 크래시를 유발합니다.
antlrcpp::Any
을 정확히 사용하여 기본 클래스를 얻으려면 어떻게해야합니까? 내가 놓친 게 분명해?
그리고 이것이 가능하지 않은 경우 어떻게해야합니까? .is() 메서드가 있지만 방문자의 반환 값을 확인하기위한 검사가 특정 유형에 불과한 경우가 많습니다 (예 : 표현식 사용시 30-40 연산자가있을 수 있음).
가능한 복제본 : [C++ 이기종 컨테이너, 형식으로 항목 가져 오기] (https://stackoverflow.com/questions/47768354/c-heterogeneous-container-get-entry-as-type). 'Base'에서 파생 된 객체를 저장해야하는 경우,'Base * '를 저장할 수 있으며 검색시 필요한 유형으로 동적 캐스트 할 수 있습니다. –
별도의 질문을하는 것이 반드시 중복되는 것은 아닙니다. 그러나 그 해결책은 여기에 적용되는 것처럼 보입니다. 'antlrcpp : Any ((Base *) value)'와'any.as ()'는 Derived 클래스를 올바르게 리턴합니다. antlrcpp :: Any가 unique_ptr을 지원하지 않아 메모리를 관리해야하므로 조금 실망 스럽습니다. 다른 방법으로 복사 할 수 있습니다. –
Thatguypat