質問は理論的なものです。
序文。
訪問者パターン:
class Visitor
{
public:
virtual void VisitElementA(const ElementA& obj) = 0;
virtual void VisitElementB(const ElementB& obj) = 0;
};
class Element
{
public:
virtual void Accept(Visitor& visitor) = 0;
};
class ElementA : public Element
{
public:
void Accept(Visitor& visitor) override { visitor.VisitElementA(*this); }
};
class ElementB : public Element
{
public:
void Accept(Visitor& visitor) override { visitor.VisitElementB(*this); }
};
この VisitElementA(const ElementA& obj) は少し見栄えが悪いので、オーバーロードを使用して次のように書き換えることができます。
class Visitor
{
public:
virtual void Visit(const ElementA& obj) = 0;
virtual void Visit(const ElementB& obj) = 0;
};
これで、ElementA と ElementB に Accept メソッドの 2 つの同一の実現ができました。
void Accept(Visitor& visitor) override { visitor.Visit(*this); }
そして、そのようなコードを ElementC、ElementD などに追加する必要があります (存在する場合)。
問題は次のとおりです。この重複を回避するにはどうすればよいですか?
Accept 実現を Element クラス (またはその他の中間クラス) 内に配置する単純な解決策は機能しません。これは、このポインターが、ElementA または ElementB ではなく、クラス Element のオブジェクトとしてオブジェクトを指すためです。コンパイル エラーが発生したり、間違った動作が発生したりします (Element にオーバーロードされた Visit メソッドが存在する場合)。
私が理解している限り、問題はコンパイル時機能と実行時機能を混在させようとすることにあります。しかし、テンプレートベースのソリューションや新しい C++11 機能、またはその他の何かが存在する可能性はありますか?
1つの注意:「マクロマジック」で解決策を提供しないでいただければ幸いです:)。