0

私は現在、問題定義用の言語用の小さなコンパイラを開発しています。Lisp と Prolog のろくでなしの子供を想像できます。さて、ケースに:

Functorは、A、B、C の 3 つのクラスが継承する基本クラスです。

ANTLR3C を使用してレクサーとパーサーを作成し、AST ツリーを作成しました。ツリーをトラバースし、型 A の関数を見つけたら、ツリーからのデータを使用して型 A のオブジェクトを作成し、それを保持する sym_register オブジェクトを作成します。

#ifndef SYM_REGISTER_H
#define SYM_REGISTER_H

#include <vector>
#include <string>

enum class Symbol_type : int { T_A, T_B, T_C, T_D };

class sym_register {
    public:
        std::string name;
        Symbol_type type;
        std::shared_ptr<Functor> declaration;
        std::vector < InstancedFunctor > result;

        sym_register(std::string n, Symbol_type t, std::shared_ptr<Functor> p){ 
            name = n; type = t; declaration = p;
        }   
};

#endif

Symbol_type enum クラスは、std::shared_ptr 宣言がどのような種類のオブジェクトであるかに関する情報を提供します。を指しているので、オブジェクトの完全な情報を取得できるはずです。

これは、シンボルをメインの Problem クラスに格納する方法です。

class Problem {
    std::map< std::string, std::shared_ptr<sym_register> > sym_table;
};

私の問題は、テーブルからシンボルを取得しようとするときです。「宣言」属性を元のクラスに取得できないため、 static_cast と reinterpret_cast を使用してみましたが、結果はありませんでした。

だから、ここで私はさまざまな質問があります:

  1. タイプ A のオブジェクトへのポインターを std::shared_ptr に格納すると、継承されたクラスからの「余分な」情報が失われますか?
  2. スイッチと (安全でない) 明示的な変換を行う必要がありますか?
  3. std::shared_ptr の代わりに NULL (a-la C) へのポインターを格納する必要がありますか?
  4. それを行う正しい方法は何ですか?

編集:私は基本的にできるようにしたい:

std::shared_ptr<A> foo = Problem.getSymbol("objectWithTypeA"); 
// and so on with the rest of the class hierarchy ...

EDIT2: コンパイル エラーは次のとおりです。

std::shared_ptr<A> foo = it.second->declaration; 
// error: conversion from ‘std::shared_ptr<Functor>’ 
// to non-scalar type ‘std::shared_ptr<A>’ requested

std::shared_ptr<A> foo(reinterpret_cast<std::shared_ptr<A> >(it.second->declaration));
// error: invalid cast from type ‘std::shared_ptr<Functor>’
// to type ‘std::shared_ptr<A>’

std::shared_ptr<A> foo(static_cast<std::shared_ptr<A> >(it.second->declaration));
// error: no matching function for call to ‘std::shared_ptr<A>::shared_ptr(std::shared_ptr<Functor>&)’
// note: candidates are:
// long list of template instantiations with a final
// note:   no known conversion for argument 1 
// from ‘std::shared_ptr<Functor>’ to ‘const std::shared_ptr<A>&’

std::shared_ptr<A> foo(static_cast<A*>(it.second->declaration));
// error: invalid static_cast from type ‘std::shared_ptr<Functor>’ to type ‘A*’

std::shared_ptr<A> foo(reinterpret_cast<A*>(it.second->declaration));
// error: invalid cast from type ‘std::shared_ptr<Functor>’ to type ‘A*’
4

2 に答える 2

2

探していませんか: std::dynamic_pointer_cast<>?

http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

std::shared_ptr<A> foo = std::dynamic_pointer_cast<A>( 
                             Problem.getSymbol("objectWithTypeA") ); 

Problem.getSymbol("objectWithTypeA")を返す場所std::shared_ptr<Functor>

オブジェクトが型でない場合A、返される shared_ptr は空になることに注意してください。

于 2013-09-24T13:35:59.563 に答える
0

この問題の「手っ取り早い」解決策は次のとおりです。

shared_ptr<A> foo = shared_ptr<A>((A *)&*it.second->declaration);

しかし、この問題に対するより良い/クリーン/安全なソリューションであるべきだと感じています(この特定の実装の有無にかかわらず)。

于 2013-09-24T13:29:09.020 に答える