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

C++ 11 operator overload with return type deduction

本文关键字:C++11 运算符 重载 返回类型      更新时间:2023-10-16

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

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

示例:

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

在您看来,实现这样一个功能的最佳方法是什么?如果有第四个更好的解决方案,我将不胜感激。

你认为这样的"互通"运营商是一个有价值的功能吗?

感谢并致以最良好的问候,Davide

这样的运算符是否"好主意"取决于您的用例。但如果你想实现它们,我建议你使用一个源自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;
}