0

boost::spirit のドキュメントでは、文法は struct を使用して定義されています。例えば、

template <typename Iterator>
struct my_grammar
    : qi::grammar<Iterator, qi::locals<std::string>, ascii::space_type >
{
    my_grammar() 
      : my_grammar::base_type(start, "start")
    {
       // using this and that
       // rules and action etc.
    }
 };

クラスを使用して記述できるかどうか疑問に思っています(そうでない場合は、なぜですか?)。私はこれをやっています。

ヘッダファイル内

 template<typename Iterator>
 class my_grammar
 {
     public:
        my_grammar();
        // rules declaration goes here.
  };

そしてソースファイルで

 template<typename Iterator>
 my_grammar::my_grammar()
       : qi::grammar::base_type(start, "start")
  {
        // write grammar and actions.
  }

名前空間は、typedef を使用して短縮されています。上記の方法を使用して書いていますが、コンパイラーが理解するのが難しいエラーが多すぎます。それは基本的に大丈夫ですか、それとも私は何か奇妙なことをしていますか?

誰かが構造体の代わりにクラスを使って文法を書いているコードを教えてもらえますか?

アップデート :

現在リンクできません。undefined reference todimacs_grammar<__gnu_cxx::__normal_iterator, std::allocator > > >::my_grammar()`と書かれています。問題は、構造体を使用しているときに書いていたことです

 my_grammar() 
  : my_grammar::base_type(start, "start")

これと同等のクラス宣言と定義を書く方法がわかりませんか?

4

2 に答える 2

4

クラスと構造体は、メンバーのデフォルトの可視性 (構造体はパブリック、クラスはプライベート) を除いて同等です。

構造体に使用した基本クラスmy_grammarからクラスを派生させるのを忘れたようです。qi::grammar<>したがって、クラス コンストラクターの実装における基本クラスの初期化子は、コンパイラーにとって意味のないものに見えます。

つまり、クラス定義を次のように変更します。

template<typename Iterator>
class my_grammar
  : public qi::grammar<Iterator, qi::locals<std::string>, ascii::space_type >
{
  public:
    my_grammar();
    // rules declaration goes here.
};

(公開継承が追加されていることに注意してください)。

編集(再:リンカーエラー):

テンプレートでは、一般に、実装はソース (.cpp) ファイルではなくヘッダー ファイルに存在する必要があります (例外はありますが)。ヘッダー ファイルでは、コンストラクター定義の構文は次のようになります。

template<typename Iterator>
my_grammar<Iterator>::my_grammar()
  : qi::grammar::base_type(start, "start")
{
    // write grammar and actions.
}

(違いは、<Iterator>以下の Ken Wayne VanderLinde によって指摘されたビットです)。

于 2012-01-05T21:50:46.337 に答える
0

私が見る唯一の問題は、

template my_grammar::my_grammar()
         : qi::grammar::base_type(start, "start")
{
      // write grammar and actions.
}

する必要があります

template<typename Iterator>
my_grammer<Iterator>::my_grammer()
: my_grammar<Iterator>::base_type(start, "start")
{
}

と同じにしたい場合struct

また、あなたclassはおそらく次のようになるはずです

template <typename Iterator>
class my_grammar
    : public qi::grammar<Iterator, qi::locals<std::string>, ascii::space_type >
于 2012-01-05T21:50:17.143 に答える