Re: Keeping type safety for classes derived from template class adapters and few good practice questions
 
Shimon Shvartsbroit <shimon1981@gmail.com> wrote:
Hello all,
template <int N, typename T>
class VectorAdapter:public boost::additive<VectorAdapter<N, T> >
{
public:
    typedef VectorAdapter<N, T>  ValueType;
    // implementation for operators manipulation
    ValueType& operator+=(const ValueType& rhs)
    {
        for (size_t i = 0; i < N; ++i)
        {
           elements_[i] += rhs.elemens_[i];
        }
        return *this;
    }
protected:
  T elements_[N];
};
By using Boost.Operators I have a non member function defined for
operator + as follows:
template <int N, typename T>
VectorAdapter<N, T> operator+(const VectorAdapter<N, T>& lhs,
                            const VectorAdapter<N, T>& rhs);
One possible solution would be to declare VectorAdapter as:
template <int N, typename T, int ClassIdNumber>
ClassIdNumber - unique number for each class derived from
VectorAdapter.
class Vector4: public VectorAdapter<4, float, 0> {..};
class Color4: public VectorAdapter<4, float, 1> {..};
class Other4: public VectorAdapter<4, float, 2> {..};
I am sure there's a better approach.
   There is, it is commonly refered to ax CRTP and it involves creating
a base class templated on the The derived class as well as what ever
other template args required.  You used it with boost::additive. Note
boot::additives template paramenter is the name of its derived class.
Now on to the 'fixing' of vector_adaptor...
template <class Derived,class T,int N>
class vector_adaptor:boost::additive<vector_adaptor<Derived,T,N> >
{
protected:
        T elements[N];
public:
        Derived & operator += (const Derived &x)
        {
                for(int i=0;i!=N;++i)
                        elements[i] += x.elements[i];
                return static_cast<Derived &>(*this);
        }
        Derived & operator -= (const Derived &x)
        {
                for(int i=0;i!=N;++i)
                        elements[i] -= x.elements[i];
                return static_cast<Derived &>(*this);
        }
        T & operator [](int x) {return elements[i];}
        const T & operator [](int x) const {return elements[i];}
};
class Vector4:public vector_adaptor<Vector4,float,4>{};
class Color4:public vector_adaptor<Color4,float,4>{};
now the classes passed to boost::aditive<...> are different and operator
+ wilth different 4 element vectors will not compile.
Not tested with boost, but It appears to solve the problem without
adding any complexity to the hierarchies involved beyond the
vector_adaptor class.  It does compile with a simple operators lookalike
on this old compiler...
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]