带有返回类型推导的C ++ 11运算符重载

时间:2015-12-31 12:59:12

标签: c++ templates c++11 decltype type-deduction

我有一个依赖于一种类型的模板类(例如template <typename T> class Vector)。现在,我想重载算术运算符,以便:

  • 我可以将它们与使用两种不同类型实例化的Vector一起使用;
  • 结果以与模板实例类型相同的方式推导出来;

示例:

Vector<float> fv = {1.5, 2.5};
Vector<int> iv = {1,2};
auto s1 = fv + iv;   // s1 MUST be of type Vector<float> == {2.5, 4.5}
auto s2 = iv + fv;   // s2 MUST be of type Vector<float> == {2.5, 4.5}

我认为,在实现矩阵,向量,多项式等的通用目的数学库中,这将是一个在可用性方面产生差异的特征。

我找到了三种使用C ++ 11获得此结果的方法

  1. ->符号

    template <typename T, typename U>
    auto operator +(const Vector<T> &lhs, const Vector<U> &rhs)
        -> Vector<decltype(lhs[0]+rhs[0])>
    {
        Vector<decltype(lhs[0]+rhs[0])> res(lhs);
        res += rhs;
        return res;
    }
    
  2. declval

    template <typename T, typename U> 
    Vector<decltype(std::declval<T>()+std::declval<U>())> 
    operator +(const Vector<T> &lhs, const Vector<U> &rhs)
    {
        Vector<decltype(lhs[0]+rhs[0])> res(lhs);
        res += rhs;
        return res;
    }
    
  3. declval作为默认类型arg

    template <typename T, typename U, 
              typename R = decltype(std::declval<T>()+std::declval<U>())> 
    Vector<R> operator +(const Vector<T> &lhs, const Vector<U> &rhs)
    {
        Vector<R> res(lhs);
        res += rhs;
        return res;
    }
    
  4. 在您看来,实施此功能的最佳方法是什么? 如果有更好的解决方案,我会很感激。

    你认为这样的&#34;互通&#34;运营商是一个有价值的功能?

    谢谢和最诚挚的问候, 的Davide

1 个答案:

答案 0 :(得分:2)

这些运营商是否是一个好主意&#34;取决于你的用例。但是如果你想实现它们,我建议你使用从std::common_type派生的traits类来获得更多的控制权:

template<typename T, typename U>
struct VectorCommonType : std::common_type<T,U> {};

template<typename T, typename U>
using VectorCommonTypeT = Vector<typename VectorCommonType<T,U>::type>;

这样你(或类的用户)可以在需要时专门化它。像这样使用它:

template<typename T, typename U> 
VectorCommonTypeT<T,U> operator+(const Vector<T> &lhs, const Vector<U> &rhs)
{
    VectorCommonTypeT<T,U> res(lhs);
    res += rhs;
    return res;
}