determining a sensible result type for a function

Hi! Let's consider this function object: template<typename TLeft, typename TRight> struct mixed_plus : public binary_function<TLeft, TRight, TLeft> { result_type operator() (first_argument_type left, second_argument_type right) const { return left + right; } };

Agoston Bejo wrote:
Hi! Let's consider this function object:
template<typename TLeft, typename TRight> struct mixed_plus : public binary_function<TLeft, TRight, TLeft> { result_type operator() (first_argument_type left, second_argument_type right) const { return left + right; } };
I think it could be: typedef decltype(*(const TLeft *)0 + *(const TRight *)0) result_type; except that decltype is merely a proposal at the moment. If you're only interested in arithmetic on built-in types, I wrote some code a while back that computes arithmetic result types. Ben. #include <boost/mpl/if.hpp> // We can't call the min() and max() functions in // std::numeric_limits<T> so we must use the old C macros to get // the limits of each type. #include <climits> #include <cwchar> // PROMOTE_HELPER tests whether a low-ranked type should be // promoted to int or to unsigned int, according to standard // section 4.5 paragraph 1. It is probably possible to write this // as a template but I don't see how. #define PROMOTE_HELPER(min, max) \ typedef boost::mpl::if_c<min >= INT_MIN && max <= INT_MAX, \ int, unsigned int>::type \ type; // The default is not to promote. template<typename T> struct promote { typedef T type; }; // The following specialisations cover the various types that // are always promoted by the usual arithmetic conversions. template<> struct promote<bool> { typedef int type; }; template<> struct promote<char> { PROMOTE_HELPER(CHAR_MIN, CHAR_MAX) }; template<> struct promote<signed char> { PROMOTE_HELPER(SCHAR_MIN, SCHAR_MAX) }; template<> struct promote<unsigned char> { PROMOTE_HELPER(0, UCHAR_MAX) }; template<> struct promote<short> { PROMOTE_HELPER(SHRT_MIN, SHRT_MAX) }; template<> struct promote<unsigned short> { PROMOTE_HELPER(0, USHRT_MAX) }; #ifndef BOOST_NO_INTRINSIC_WCHAR_T template<> struct promote<wchar_t> { typedef boost::mpl::if_c< WCHAR_MIN >= INT_MIN && WCHAR_MAX <= INT_MAX, int, boost::mpl::if_c< WCHAR_MIN >= 0 && WCHAR_MAX <= UINT_MAX, unsigned, boost::mpl::if_c< WCHAR_MIN >= LONG_MIN && WCHAR_MAX <= LONG_MAX, long, unsigned long>::type>::type>::type type; }; #endif template<typename T> struct rank; template<> struct rank<int> { enum { value = 0 }; }; template<> struct rank<unsigned> { enum { value = 1 }; }; template<> struct rank<long> { enum { value = 2 }; }; template<> struct rank<unsigned long> { enum { value = 3 }; }; template<> struct rank<float> { enum { value = 4 }; }; template<> struct rank<double> { enum { value = 5 }; }; template<> struct rank<long double> { enum { value = 6 }; }; template<typename T, typename U> struct arith_result_helper { typedef typename boost::mpl::if_c< rank<T>::value >= rank<U>::value, T, U>::type type; }; #if UINT_MAX > LONG_MAX template<> struct arith_result_helper<unsigned, long> { typedef unsigned long type; }; template<> struct arith_result_helper<long, unsigned> { typedef unsigned long type; }; #endif template<typename T, typename U> struct arith_result { typedef typename arith_result_helper< typename promote<T>::type, typename promote<U>::type> ::type type; };
participants (2)
-
Agoston Bejo
-
Ben Hutchings