Класс v / s структура в boost :: spirit - PullRequest
0 голосов
/ 06 января 2012

В документации 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.
  }

Пространство имен было закорочено с использованием typedefs.Я пишу с использованием вышеуказанного метода, и компилятор выдает мне слишком много ошибок, которые трудно понять.Это в принципе нормально или я делаю что-то странное?

Можете ли вы указать мне какой-нибудь код, где кто-то использовал класс вместо struct для написания грамматики?

ОБНОВЛЕНИЕ:

Я не могу связать сейчас.В нем говорится, что undefined reference to dimacs_grammar <__ gnu_cxx :: __ normal_iterator, std :: allocator>>> :: my_grammar () `.Проблема в том, что при использовании struct я писал

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

Я не уверен, как написать эквивалентное объявление класса и определение для этого?

Ответы [ 2 ]

4 голосов
/ 06 января 2012

Классы и структуры эквивалентны, за исключением видимости членов по умолчанию (общедоступной для структур, закрытой для классов).

Похоже, что вы забыли сделать свой класс 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.
};

(Обратите внимание на добавленное публичное наследство).

РЕДАКТИРОВАТЬ (re: linker error):

При использовании шаблонов, как правило, реализация должна находиться в файле заголовка, а не в исходном (.cpp) файле (хотя есть исключения). В вашем заголовочном файле синтаксис определения конструктора должен быть:

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

(разница - бит <Iterator>, как указано Кеном Уэйном ВандерЛинде ниже).

0 голосов
/ 06 января 2012

Единственная проблема, которую я вижу, состоит в том, что

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 >
...