This is a trick to constrain function templates -- to restrict the class of types. There are lots of concepts like vector expression, scalar expression, matrix expression etc. If you want to write a function template that multiplies a vector with a scalar you could try to write
template<typename V, typename S>
some_type operator*(V v, S s); // vector * scalar
template<typename V, typename S>
some_type operator*(S s, V v); // scalar * vector
but this is not going to work because both declarations are essentially equivalent and nobody said that V is supposed to be a vector expression and S is supposed to be a scalar expression. So, what the uBlas developers did is to use the CRTP to constrain these templates:
template<typename V, typename S>
some_Type operator*(vector_expression<V> ve, scalar_expression<S> se);
To make this work all scalar expressions S have to derive from scalar_expression<S>
and all vector expressions V have to derive from vector_expression<V>
. This way this operator is only considered if the fist operand is really an expression for a vector and the second argument is really an expression for a scalar. You can overload this function template with a second one that swaps both parameters and everything is okay.
Now, to be able to access anything from V and S (the derived types) we need a cast from base class to derived class. This is what the conversion operator in the base class is for. Since the base class knows the derived class (it is a template parameter), this is not a problem. It makes sense to choose the weakest cast operator that allows this cast to avoid errors. This is the static_cast
. It can be used to convert base* to derived* without any significant overhead.
I don't understand what you try to do with your code
template<class E>
class vector_expression2 : private vector_expression<E>;
If you want to write your own vector expression as a template you would do it like this:
template<class E>
class my_parameterized_vector_expression
: public vector_expression<my_parameterized_vector_expression<E> >;
I don't think it works with private inheritance. At least all the function templates that take a vector expression as argument won't be able to access the conversion operator from the base class if you use private inheritance here.