###

Question:

am trying to understand pattern used in ublas. pattern is such:

`struct vector : vector_expression<vector> `

where vector_expression is like this:

`template<class E> class vector_expression { ... // no constructor or E pointer/reference in class // const E &operator () () const { return *static_cast<const E*>(this); } `

complete source code is here: http://www.tena-sda.org/doc/5.2.2/boost/dd/d44/vector__expression_8hpp-source.html#l00088

my question is, how does `*static_cast<const E*>(this)`

work? does it rely on inheritance?

next question: if I derive

`template<class E> class vector_expression2 : private vector_expression<E> { //friend class ublas::vector_expression<E>; // this is the fix typedef vector_expression<E> base; const E& operator()() const { return base::operator()(); } }; `

i get compiler error regarding inaccessible `vector_expression`

base in static cast. why does it happen?

Thank you

###

Solution:1

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.

###

Solution:2

The accessibility error that you are referring to does not make sense. `vector_expression`

is a `struct`

and the function call `operator ()`

is public. Perhaps you tried to invoke `vector_expression2::operator ()`

? That would have given you an error because you defined that operator as private.

The solution to you problem might be even simpler than you think. If you look through the ublas source code you would see that any classes deriving `vector_expression`

pass themselves as the template argument:

`template<class M> class matrix_row: public vector_expression<matrix_row<M> > { }; `

What this means is that `vector_expression`

can cast the template parameter to itself because the template parameter derives from `vector_expression`

, hence `*static_cast<const E*>(this)`

works, which is just a fancy way to say `*((const E*)this)`

.

Try to rewrite `vector_expression2`

class like so:

`template<class E> class vector_expression2 : public vector_expression<vector_expression2<E>> { }; `

**Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com**

EmoticonEmoticon