. , , : CRTP , . Derived1 Derived2 , ... , , , . .
, ( , , ). , Base, - . , Base, apply, :
class Base;
class Derived1;
class Derived2;
struct Visitor {
virtual void visit( Base& ) = 0;
virtual void visit( Derived1& ) = 0;
virtual void visit( Derived2& ) = 0;
};
struct Base {
virtual void apply( Visitor& v ) {
v.visit( *this );
}
template <typename T> void foo(T);
};
template <typename T>
struct FooCaller : Visitor {
T& ref_value;
FooCaller( T& v ) : ref_value(v) {}
template <typename U> void call_foo( U& o ) {
o.foo(ref_value);
}
virtual void visit( Base & b ) { call_foo(b); }
virtual void visit( Derived1 & d1 ) { call_foo(d1); }
virtual void visit( Derived2 & d2 ) { call_foo(d2); }
};
, , Visitor, ( , , ).
:
int main()
{
Base* BasePtr = new Derived1();
int i = 5;
FooCaller<int> c(i)
BasePtr->apply(c);
}
i c , ( ) const-. , [1] ++ Derived1::apply, , BasePtr. Visitor::visit( Derived1& ) . FooCaller<int>::visit( Derived1& ), . FooCaller<int>::visit call_foo, U Derived1, Derived1::foo, int, Derived1::foo<int>... ...
( , CRTP, ) ( : Base Visitor), , , . .
, , , , , ... , , , , .
, ++, , , , : .