2013-11-24 14 views
2

我宣布一个模板Matrix类是这样的:有条件的模板返回类型在C++

template<typename Type> class Matrix { 
    // Some code for matrix computations 
} 

现在,我想超载operator+在保证了更大的类型将是结果的方式。我一直想把这事

template<typename OtherType> 
Matrix<Type> operator+ (Matrix<OtherType> mat) { 
    // Dimension check and matrix addition code 
} 

但这样做,我就几乎迫使C++选择Matrix<Type>作为返回类型。我想实现的是,例如,Matrix<int> + Matrix<float>将导致Matrix<float>

有关如何做到这一点的任何建议?

+0

'float's不能存储每个'int'值。 – Yakk

回答

5

可以使用一个编译时的条件:

template< 
    typename OtherType, 
    typename T = typename std::conditional<(sizeof(Type) <= sizeof(OtherType)), 
        OtherType, Type>::type 
> 
Matrix<T> operator+ (const Matrix<OtherType>& mat); 

,或者使用C++ 11特征decltype推断类型:

template<typename OtherType> 
auto operator+ (const Matrix<OtherType>& mat) 
    -> Matrix<decltype(std::declval<OtherType>() + std::declval<Type>())>; 
+0

+1。 – deeiip

+1

请注意,使用sizeof做它有点奇怪,因为它是否选择int64_t或double(同样int32_t或float)将取决于哪个参数在左侧。 –

3

可以在该简化示例中模拟这种问题:

#include <type_traits> 

template <typename T, typename U> 
typename std::common_type<T, U>::type add(T x, U y) 
{ 
    return x + y; 
} 

或者:

template <typename T, typename U> 
auto add(T x, U y) -> decltype(x + y) 
{ 
    return x + y; 
} 

这两种解决方案通常不完全一样,但应该用于基本算术运算。

+0

好吧,'Matrix const&x,Matrix const&y) - > Matrix ' – Yakk

0

您需要一个映射来描述给定类型组合应该选择哪种类型。例如(只是做了浮点类型,它可以扩展,当然):

template <typename, typename> struct best_type; 
template <typename T> struct best_type<T, T> { typedef T type; }; 
template <> best_type<float, double> { typdef double type; }; 
template <> best_type<double, float> { typdef double type; }; 
template <> best_type<float, long double> { typdef long double type; }; 
template <> best_type<long double, float> { typdef long double type; }; 
template <> best_type<double, long double> { typdef long double type; }; 
template <> best_type<long double, double> { typdef long double type; }; 


template <typename T0, typename T1> 
Matrix<typename best_type<T0, T1>::type> 
operator+ (Matrix<T0> const& m0, Matrix<T1> const& m1) { 
    // ... 
} 

operator+()被配制成非成员,但它可以,也成为其成员(通常它为operator+()更好成为潜在委托给成员operator+=()的非会员)。