How to implicitly cast between C++ templates with different template parameters -
i trying create c++ template class wrapping integer value , checking value inside valid range, simplified code following one:
struct outofrangeerror { }; template<int min, int max, typename type> struct integerrange { private: type mvalue; public: integerrange(const type value) : mvalue(value) { if (min > value || value > max) { throw outofrangeerror(); } } operator type() const { return mvalue; } }
the previous code works has little drawback when using class. here sample:
typedef integerrange<0, 4, int> range1_t; typedef integerrange<0, 5, int> range2_t; range1_t = 3; //range2_t b = a; // not work range2_t b = static_cast<int>(a); // works ok
so, assign values between different ranges have explicitly cast type given. have solution avoid having explicit cast , dealing integerrange class normal integers. developer should have feeling dealing normal integer instead of classes.
to solve tried different things. 1 working following 1 additional constructor:
template<typename range_type> integerrange(const range_type &value) : mvalue(static_cast<const type>(value)) { if (min > mvalue || mvalue > max) { throw outofrangeerror(); } }
however, if works, not range_type can type able cast type, , restrict integerrange classes. restrict integerrange classes tried following not compiling , not understand reason:
template<int arg_min, int arg_max, typename arg_type> integerrange(const integerrange<arg_min, arg_max, typename arg_type> &value) : mvalue(static_cast<const type>(value)) { if (min > value || value > max) { throw outofrangeerror(); } }
the questions 2:
* why last piece of code not compiling , need change compile it.
* there better avoid explicit cast missing?
thanks
first, you shouldn't use arg_max
template name since may defined posix numeric constant.
secondly, should remove typename
in third template argument of integerrange
:
integerrange(const integerrange<arg_min, arg_max, arg_type> &value) :
also maybe should cast value
arg_type
directly call operator arg_type()
, let compiler convert arg_type
type
instead of casting type
, let compiler infer possible conversion arg_type
, call operator arg_type()
. first solution, compilation errors regarding impossible conversions may more explicit.
Comments
Post a Comment