これがC++03の答えです。C ++11の場合-auto/decltypeを使用します(他の回答を参照)。
別のテンプレートを作成する必要がありますtemplate CommonNumericType<T1,T2>
::
template <typename L, typename R>
typename CommonNumericType<T1,T2>::Type max(L x, R y)
{
return x>y ? x : y;
}
そして、このCommonNumericTypeを、可能な数値タイプのすべてのペアに特化します。
template <typename L, typename R>
struct CommonNumericType;
template <typename T>
struct CommonNumericType<T,T> {
typedef T Type;
};
template <typename L>
struct CommonNumericType<L,long double> {
typedef long double Type;
};
template <typename R>
struct CommonNumericType<long double,R> {
typedef long double Type;
};
// ...
template <>
struct CommonNumericType<int,short> {
typedef int Type;
};
// and many others stuff
いくつかの数値型の階層(int型の前にfloat型)を作成することを考えることができます。<number of numeric types>^2
かなり大きいので:
template <typename T>
struct NumericTypeOrder;
template <>
struct NumericTypeOrder<long double> { enum { VALUE = 1 }; };
template <>
struct NumericTypeOrder<double> { enum { VALUE = 2 }; };
template <>
struct NumericTypeOrder<float> { enum { VALUE = 3 }; };
template <>
struct NumericTypeOrder<unsigned long long> { enum { VALUE = 4 }; };
// etc for all numeric types - where signed char is last one...
template <typename L, typename R, bool L_bigger_than_R>
struct CommonNumericTypeImpl;
template <typename L, typename R>
struct CommonNumericTypeImpl<L,R,true> {
typedef L type;
};
template <typename L, typename R>
struct CommonNumericTypeImpl<L,R,false> {
typedef R type;
};
template <typename L, typename R>
struct CommonNumericType
: CommonNumericTypeImpl<L,R,NumericTypeOrder<L>::value >= NumericTypeOrder<R>::value > {
};
または、マクロを使用します。
#define max(l,r) ((l) >= (r) ? (l) : (r))
ずっと簡単ですね。