Возможно, вы могли бы использовать std::plus<T>
, std::minus<T>
, std::multiplies<T>
и std::divides<T>
. Однако они будут работать только в том случае, если оба операнда имеют одинаковый тип, или, возможно, если левый операнд можно преобразовать в тип первого.
Я не вижу способа добиться того, что вы пытаетесь сделать, кроме как с помощью препроцессора. Есть веские причины не хотеть макросов?
Если вы хотите убедиться, что тип возвращаемого значения достаточно большой, чтобы содержать результат, вы можете сделать что-то подобное:
#include <functional>
#include <boost/mpl/if_.hpp>
// Metafunction returning the largest type between T and U
// Might already exist in Boost but I can't find it right now...maybe
// boost::math::tools::promote_args
template <typename T, typename U>
struct largest :
boost::mpl::if_<
boost::mpl::bool_<(sizeof(T) > sizeof(U))>,
T,
U
>
{};
template <typename T, typename U, template <typename S> class Op>
struct Foo
{
typedef typename largest<T, U>::type largeType;
largeType bar(const T & t, const U & u)
{
return Op<largeType>()(t, u); // Applies operator+
}
};
int main()
{
Foo<int, double, std::plus> f;
double d = f.bar(12, 13.0); // takes int and double, returns double
}
Здесь я использовал Boost MPL , чтобы написать метафункцию largest
, но вы можете написать свою собственную метафункцию if
, если вы не можете использовать Boost (шаблон класса, параметризованный двумя типами, и bool, специализированный за истину и ложь).
Чтобы определить тип возвращаемого выражения, вы также можете взглянуть на boost :: result_of , который, если я правильно понимаю, эквивалентен предстоящему оператору decltype
в C ++ 0x .