i read wikipedia article curiously recurring template pattern in c++ doing static (read: compile-time) polymorphism. wanted generalize change return types of functions based on derived type. (this seems should possible since base type knows derived type template parameter). unfortunately, following code won't compile using msvc 2010 (i don't have easy access gcc right haven't tried yet). know why?
template <typename derived_t> class base { public: typedef typename derived_t::value_type value_type; value_type foo() { return static_cast<derived_t*>(this)->foo(); } }; template <typename t> class derived : public base<derived<t> > { public: typedef t value_type; value_type foo() { return t(); //return t object (assumes t default constructable) } }; int main() { derived<int> a; }
btw, have work-around using template parameters, don't it---it verbose when passing many types inheritance chain.
template <typename derived_t, typename value_type> class base { ... }; template <typename t> class derived : public base<derived<t>,t> { ... };
edit:
the error message msvc 2010 gives in situation error c2039: 'value_type' : not member of 'derived<t>'
g++ 4.1.2 (via codepad.org) says error: no type named 'value_type' in 'class derived<int>'
derived
incomplete when use template argument base
in base classes list.
a common workaround use traits class template. here's example, traitsified. shows how can use both types , functions derived class through traits.
// declare base_traits traits class template: template <typename derived_t> struct base_traits; // define base class uses traits: template <typename derived_t> struct base { typedef typename base_traits<derived_t>::value_type value_type; value_type base_foo() { return base_traits<derived_t>::call_foo(static_cast<derived_t*>(this)); } }; // define derived class; can use traits too: template <typename t> struct derived : base<derived<t> > { typedef typename base_traits<derived>::value_type value_type; value_type derived_foo() { return value_type(); } }; // declare , define base_traits specialization derived: template <typename t> struct base_traits<derived<t> > { typedef t value_type; static value_type call_foo(derived<t>* x) { return x->derived_foo(); } };
you need specialize base_traits
types use template argument derived_t
of base
, make sure each specialization provides of members base
requires.
Comments
Post a Comment