Given a base class, that contains the public static method with the general logic for all the derived classes (such as creating them). Parametrizing types of child class template are passed to the base class template (along with the type of the child class in order to have access to its custom static methods in the static method of the base class). From combinations of these types are typedefed new "types" (this is done in the base class to avoid a duplication of some code). They then re-typedefed (similar) in public sections of derived classes. I would use these type definitions into the class containing the helpers, as follows:
#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
template< class DERIVED >
class HELPERS;
template< class V, class DERIVED >
struct BASE
{
typedef typename V::value_type F;
static
F some_common_operation()
{
return helpers.approximate_x(DERIVED::value()); // some common logic (HELPERS::approximate_x() here) depending on the value of DERIVED::value()
}
static
DERIVED create_biased(F const & x)
{
return DERIVED(F(0.5) * (x + some_common_operation()));
}
protected :
BASE(F const & x_)
: x(x_)
{ ; }
F x;
private :
static
HELPERS< DERIVED > const helpers;
};
template< class V, class DERIVED >
HELPERS< DERIVED > const BASE< V, DERIVED >::helpers;
template< class V >
class DERIVED
: public BASE< V, DERIVED< V > >
{
typedef BASE< V, DERIVED< V > > B;
friend B;
public :
typedef typename B::F F;
DERIVED(F const & x_)
: B(x_)
{ ; }
F shape(F const & y) const
{
return y * x;
}
private :
static constexpr
F value()
{
return F(2.0L); // custom data
}
using B::x;
};
// template< class > class DERIVED1;...
template< class D >
struct HELPERS // set of helpers, that operates on classes derived from BASE
{
typedef typename D::F F; // error: no type named <F> in <class DERIVED<std::vector<double> >>
F approximate_x(F const & x) const
{
using std::sqrt;
return sqrt(x);
}
};
int main()
{
DERIVED< std::vector< double > > d(2.0L);
return EXIT_SUCCESS;
}
I'm trying to get the definition in the helpers class, but I get an error (g++ -std=gnu++11 a.cpp).
a.cpp: In instantiation of «struct HELPERS<DERIVED<std::vector<double> > >»:
a.cpp:44:26: required from «struct BASE<std::vector<double>, DERIVED<std::vector<double> > >»
a.cpp:47:7: required from «class DERIVED<std::vector<double> >»
a.cpp:97:39: required from here
a.cpp:85:27: error: no type named «F» in «class DERIVED<std::vector<double> >»
What is wrong? Typedef and all its "ancestors" are accessible (placed in public sections) in the chain of classes.