2013-11-24 20 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+=()的非會員)。