2017-12-13 7 views
2

私は現在、ANTLR4のC#バージョンからC++ターゲットにいくつかのコードを移植していますが、現在いくつかの問題が発生しています。私がASTをC#で構築したのは、基本クラス(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_castdynamic_castを変えしかし、多分

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

だと思ったし、それがキャストされます"Base"を出力します。また、Cスタイルのキャスティングでは、データメンバーにアクセスするとクラッシュが発生します。

antlrcpp::Anyはどのくらい正確にベースクラスを取得しますか?私が紛失していることは明らかですか?

これができない場合は、これをどうすれば解決できますか? .is()メソッドがありますが、ビジターの戻り値が特定の型であるかどうかを確認することは実行できません(式を使用すると、30〜40の演算子が存在する可能性があります)。

+0

可能な重複:[C++異種コンテナ、タイプとしてエントリを取得](https://stackoverflow.com/questions/47768354/c-heterogeneous-container-getentry-as-type)。 'Base'から派生したオブジェクトを格納する必要がある場合は、' Base * 'を格納し、検索時に必要な型に動的キャストすることができます。 –

+0

別々の質問をしているので必ずしも重複しているわけではありません。しかし、その解決策はここでは適用可能と思われる。 'antlrcpp:Any((Base *)value)'と 'any.as ()'はDerivedクラスを正しく返します。 antlrcpp :: Anyはunique_ptrをサポートしていないので、少し残念です。今はメモリを管理する必要があります。それ以外の方法でコピーします。 – Thatguypat

答えて

1

この種のシナリオでは、antlrcpp::anyクラスは作成されていません。普遍的なVariant実装ではありません。

タイプイレーズでは機能しないさまざまなタイプなどに対して、ユニオンを使用して独自のバリアント実装について考える必要がある場合。

コピーセマンティクスをサポートしていないため、ユニークなポインタは一般的にこのコンテキストではあまりいい考えではないでしょう(ここではそれが必要です)。訪問者の評価はshared_ptrで行ってください。

+0

コメントとこの回答を組み合わせても問題ありません。 'shared_ptr 'を使い、すべての私の派生物を 'Base'としてキャスティングすることは、生ポインタを使ったメモリの問題を解決し、完全に動作します。なぜ自分のバリアントクラスを実装する必要があるのか​​わかりません。 – Thatguypat

関連する問題