Оператор присваивания C ++ Move - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь использовать перегрузку операторов '&' и '|'и операторы '| =' в C ++ для создания BNF (Backus Naur Form), встроенной в C ++.Два существенных класса в этом встроенном BNF - это класс Terminal и класс NonTerminal.

В качестве примера Snippet рассмотрим описание BNF списка символов «a» или «b»:

Terminal _a('a'), _b('b');
NonTerminal list, token;

token |= _a | _b;

list |= token | token & list;   

// Parse a string of 'a's and 'b's
if(list.match("baabaabaa"))
  cout << "matched!!!";
else
  cout << "failed!!!";

// Test the token nonterminal
token.match("a");

Определения классов следующие: они ничего не делаютна данный момент, но служат проверкой логики.

using namespace std;

class Sequence;
class Production;

class Base {
  Base() {}
  virtual ~Base() {}

  friend Sequence operator & (const Base& lhs, const Base& rhs);
  friend Production operator | (const Base& lhs, const Base& rhs);

  virtual bool match(string) const { return false; }
};

class Terminal : public Base {
  char token;
public:
  Terminal(char c) : token(c) {}
  virtual ~Terminal() {}

  virtual bool match(string s) const { return true; }  
};

class Sequence : public Base {
  const Base& lhs;
  const Base& rhs;
public:
  Sequence(const Base& lhs, const Base& rhs) : lhs(lhs), rhs(rhs) {}
  virtual ~Sequence() {} 
  virtual bool match(string s) const { return lhs.match(s) && rhs.match(s); }
};

class Production: public Base {
  const Base& lhs;
  const Base& rhs;
public:
  Production(const Base& lhs, const Base& rhs) : lhs(lhs), rhs(rhs) {}
  virtual ~Production() {} 
  virtual bool match(std::string s) const { return lhs.match(s) || rhs.match(s); }
};

Последнее определение класса, NonTerminal, - это то, где у меня возникают проблемы.И проблема заключается в семантике перемещения C + 11.

class NonTerminal : Base {
  Base dummy; // Needed to make initialization work.
  Base& ref; // Or maybe Base&& ref or possibly Base ref or could it be Base* ref?

  NonTerminal() : ref(dummy) {}
  virtual ~NonTerminal() {}

  // Used when rhs is of type Sequence or Production
  void operator |= (Base&& rhs) {
    // The desired action is to capture rhs and keep it in memory.
    ref = move(rhs); 
  }

  // Used when rhs is of type Terminal
  void operator |= (const Base& rhs) {
    // The desired action is to reference rhs. 
    ref = rhs;
  }

  virtual bool match(string s) { return ref.match(s); } 
};

Код, основанный на приведенном выше примере, основан на компиляции, но когда вызывается метод list.match (), он вызывает метод Base :: match (), а не Production :: match (), что является ожидаемым поведением.Таким же образом, вызов token.match () также вызывает метод Base :: match (), а не Terminal :: match ().Итак, как мне вызвать правильные перезаписанные методы сопоставления и сделать это правильно для значения r, полученного в первом операторе | = метод?

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...