【问题标题】:Conditional template return type in C++C++ 中的条件模板返回类型
【发布时间】:2013-12-09 03:53:48
【问题描述】:

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

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&lt;Type&gt; 作为返回类型。我想要实现的是,例如,Matrix&lt;int&gt; + Matrix&lt;float&gt; 将导致Matrix&lt;float&gt;

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

【问题讨论】:

  • floats 不能存储每个 int 值。

标签: c++ templates types matrix return


【解决方案1】:

您可以使用编译时条件:

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

【讨论】:

  • 请注意,使用 sizeof 执行此操作有点奇怪,因为它选择 int64_t 还是 double(同样是 int32_t 或 float)将取决于左侧的参数。
【解决方案2】:

你可以在这个简化的例子中模拟这个问题:

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

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

【讨论】:

  • 好吧,Matrix&lt;T&gt; const&amp; x, Matrix &lt;U&gt; const&amp; y) -&gt; Matrix&lt; decltype( x(0,0) + y(0,0)) &gt;
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2022-01-11
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 2015-12-14
    相关资源
    最近更新 更多