[units] User-defined vector class template won't compile
I'm trying to make a "simple" cartesian vector class. It should be similar to the quaternion example that you give in the docs, but I can't get it to compile. I've attached a complete program. Here are the error I get when I try to compile it. Lets just focus on fixing the first few errors about no binary '*'. When I understand that, perhaps I'll be able to fix the rest. Thanks, terry try.cpp using native typeof C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : error C2678: binary '*' : no operator found which takes a left-hand operand of type 'double' (or there is no acceptable conversion) C:/boost/boost_1_43_0\boost/units/detail/one.hpp(47): could be 'T boost::units::operator *<T>(const boost::units::one &,const T &)' with [ T=rci::cartesian::vector<3,double> ] C:/boost/boost_1_43_0\boost/units/detail/one.hpp(53): or 'T boost::units::operator *<double>(const T &,const boost::units::one &)' with [ T=double ] C:/boost/boost_1_43_0\boost/units/detail/one.hpp(58): or 'boost::units::one boost::units::operator *(const boost::units::one &,const boost::units::one &)' while trying to match the argument list '(double, rci::cartesian::vector<Dim,Rep>)' with [ Dim=3, Rep=double ] C:/boost/boost_1_43_0\boost/units/operators.hpp(75) : see reference to class template instantiation 'boost::units::multiply_typeof_helper<X,Y>::nested' being compiled with [ X=double, Y=rci::cartesian::vector<3,double> ] C:/boost/boost_1_43_0\boost/units/quantity.hpp(690) : see reference to class template instantiation 'boost::units::multiply_typeof_helper<X,Y>' being compiled with [ X=double, Y=rci::cartesian::vector<3,double> ] try.cpp(255) : see reference to class template instantiation 'boost::units::multiply_typeof_helper<X,Y>' being compiled with [ X=boost::units::quantity<boost::units::si::length>, Y=rci::cartesian::vector<3,double> ] C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : error C2866: 'boost::units::multiply_typeof_helper<X,Y>::nested::_typeof_register_value' : a const static data member of a managed type must be initialized at the point of declaration with [ X=double, Y=rci::cartesian::vector<3,double> ] C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : error C2027: use of undefined type 'boost::type_of::msvc_extract_type<ID>::id2type_impl<__formal>' with [ ID=boost::units::multiply_typeof_helper<double,rci::cartesian::vector<3,double>>::nested ] and [ __formal=true ] C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : error C2146: syntax error : missing ';' before identifier 'type' C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : error C2602: 'boost::units::multiply_typeof_helper<X,Y>::nested::type' is not a member of a base class of 'boost::units::multiply_typeof_helper<X,Y>::nested' with [ X=double, Y=rci::cartesian::vector<3,double> ] C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : see declaration of 'boost::units::multiply_typeof_helper<X,Y>::nested::type' with [ X=double, Y=rci::cartesian::vector<3,double> ] C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : see declaration of 'boost::units::multiply_typeof_helper<X,Y>::nested' with [ X=double, Y=rci::cartesian::vector<3,double> ] C:/boost/boost_1_43_0\boost/units/operators.hpp(74) : error C2868: 'boost::units::multiply_typeof_helper<X,Y>::nested::type' : illegal syntax for using-declaration; expected qualified-name with [ X=double, Y=rci::cartesian::vector<3,double> ] try.cpp(255) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'boost::units::quantity<Unit,Y>' (or there is no acceptable conversion) with [ Unit=boost::units::unit<boost::units::length_dimension,boost::units::si::system>, Y=int ] try.cpp(28): could be 'rci::cartesian::vector<Dim,Rep> &rci::cartesian::vector<Dim,Rep>::operator =(const rci::cartesian::vector<Dim,Rep> &)' with [ Dim=3, Rep=boost::units::quantity<boost::units::si::length> ] while trying to match the argument list '(rci::cartesian::vector<Dim,Rep>, boost::units::quantity<Unit,Y>)' with [ Dim=3, Rep=boost::units::quantity<boost::units::si::length> ] and [ Unit=boost::units::unit<boost::units::length_dimension,boost::units::si::system>, Y=int ]
I'm trying to make a "simple" cartesian vector class. It should be similar to the quaternion example that you give in the docs, but I can't get it to compile. I've attached a complete program. Here are the error I get when I try to compile it. Lets just focus on fixing the first few errors about no binary '*'. When I understand that, perhaps I'll be able to fix the rest.
One problem is here : // vector * T template<int Dim, class T1, class T2> inline typename boost::units::multiply_typeof_helper<T2, vector<Dim, T1> >::type operator*(const vector<Dim, T1>&lhs, const T2& rhs) { return rhs * lhs; } Since multiply_typeof_helper<T1,T2> is really just a glorified version of typeof(T1()*T2()), what you're saying here is that the return type of the product of a vector and a scalar is the return type of the product of a vector and a scalar. You need to define the top-level multiply operation; define it something like this : // vector * T template<int Dim, class T1, class T2> inline vector<Dim,typename boost::units::multiply_typeof_helper<T2, T1 >::type> operator*(const vector<Dim, T1>&lhs, const T2& rhs) { //return rhs * lhs; this return statement is also wrong, since it is recursive, defining the returned value in terms of the operator itself...} Cheers, Matthias
Your reply provided the key, thank you. I misunderstood what multiply_typeof_helper was for. It's like common_type<> in C++0X, but its more specialized for each kind of operator. Which is obviously important for units. My program compiles and runs now. Thanks again. terry BTW, the return statement is not recursive, because it swaps the lhs and rhs. // vector * T template<int Dim, class T1, class T2> inline typename boost::units::multiply_typeof_helper<T2, vector<Dim, T1> >::type operator*(const vector<Dim, T1>&lhs, const T2& rhs) { return rhs * lhs; } Since multiply_typeof_helper<T1,T2> is really just a glorified version of typeof(T1()*T2()), what you're saying here is that the return type of the product of a vector and a scalar is the return type of the product of a vector and a scalar. You need to define the top-level multiply operation; define it something like this : // vector * T template<int Dim, class T1, class T2> inline vector<Dim,typename boost::units::multiply_typeof_helper<T2, T1 >::type> operator*(const vector<Dim, T1>&lhs, const T2& rhs) { //return rhs * lhs; this return statement is also wrong, since it is recursive, defining the returned value in terms of the operator itself...} Cheers, Matthias
participants (2)
-
Matthias Schabel
-
Terry Golubiewski