C ++移动赋值运算符

时间:2019-01-21 20:15:43

标签: c++11

我正在尝试使用'&'和'|'的运算符重载和C ++的'| ='运算符,以创建嵌入在C ++中的BNF(Backus Naur Form)。 此嵌入式BNF中的两个重要类是Terminal类和NonTerminal类。

作为示例代码段,请考虑字符“ a”或“ b”的列表的BNF描述:

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()而不是生产行为::: match(),这是预期的行为。以相同的方式,调用token.match()还会调用方法Base :: match()而不是Terminal :: match()。那么,如何获得正确的被覆盖的match方法,并为第一个运算符| =方法中接收到的右值正确地实现呢?

谢谢

0 个答案:

没有答案