訪問者パターンの典型的な実装では、クラスは基本クラスのすべてのバリエーション (子孫) を考慮する必要があります。ビジター内の同じメソッド コンテンツが異なるメソッドに適用される場合が多数あります。この場合、テンプレート化された仮想メソッドが理想的ですが、現時点では許可されていません。
では、テンプレート化されたメソッドを使用して、親クラスの仮想メソッドを解決できますか?
与えられた(基礎):
struct Visitor_Base; // Forward declaration.
struct Base
{
virtual accept_visitor(Visitor_Base& visitor) = 0;
};
// More forward declarations
struct Base_Int;
struct Base_Long;
struct Base_Short;
struct Base_UInt;
struct Base_ULong;
struct Base_UShort;
struct Visitor_Base
{
virtual void operator()(Base_Int& b) = 0;
virtual void operator()(Base_Long& b) = 0;
virtual void operator()(Base_Short& b) = 0;
virtual void operator()(Base_UInt& b) = 0;
virtual void operator()(Base_ULong& b) = 0;
virtual void operator()(Base_UShort& b) = 0;
};
struct Base_Int : public Base
{
void accept_visitor(Visitor_Base& visitor)
{
visitor(*this);
}
};
struct Base_Long : public Base
{
void accept_visitor(Visitor_Base& visitor)
{
visitor(*this);
}
};
struct Base_Short : public Base
{
void accept_visitor(Visitor_Base& visitor)
{
visitor(*this);
}
};
struct Base_UInt : public Base
{
void accept_visitor(Visitor_Base& visitor)
{
visitor(*this);
}
};
struct Base_ULong : public Base
{
void accept_visitor(Visitor_Base& visitor)
{
visitor(*this);
}
};
struct Base_UShort : public Base
{
void accept_visitor(Visitor_Base& visitor)
{
visitor(*this);
}
};
基礎が築かれたので、キッカーの出番です (テンプレート化されたメソッド):
struct Visitor_Cout : public Visitor_Base
{
template <class Receiver>
void operator() (Receiver& r)
{
std::cout << "Visitor_Cout method not implemented.\n";
}
};
意図的に、メソッド宣言Visitor_Cout
にキーワードが含まれていません。virtual
メソッド シグネチャの他のすべての属性は、親の宣言 (または仕様) と一致します。
全体像として、この設計により、開発者は、ターゲット オブジェクト (訪問を受け取るオブジェクト) のタイプのみが異なる共通の訪問機能を実装できます。上記の実装は、派生ビジターの実装がオプションのメソッドを実装していない場合のアラートに対する私の提案です。
これは C++ 仕様で合法ですか?
(コンパイラXXXで動作すると言う人もいますが、これは一般的な言語に対する質問です。)