C++中的条件模板返回类型

Conditional template return type in C++

本文关键字:返回类型 条件 C++      更新时间:2023-10-16

我以这种方式声明了一个模板化的Matrix类:

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

现在,我正在尝试重载operator+,以确保结果是较大的Type。我在尝试这个东西:

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

但如果这样做,我实际上会强制C++选择Matrix<Type>作为返回类型。我想要实现的是,例如,Matrix<int>+Matrix<float>将产生Matrix<float>

有什么建议吗?

您可以使用编译时条件:

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>())>;

您可以在这个简化的示例上对这个问题进行建模:

#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;
}

一般来说,这两种解决方案并不完全相同,但应该用于基本算术运算。

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

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+=()的非成员效果更好)。