【发布时间】:2015-12-31 12:59:12
【问题描述】:
我有一个依赖于一种类型的模板类(例如template <typename T> class 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 获得此结果的方法
-
->表示法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; } -
declvaltemplate <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; } -
declval作为默认类型 argtemplate <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; }
在您看来,实现此类功能的最佳方法是什么? 如果有第四个更好的解决方案,我将不胜感激。
您认为这种“互通”运算符是一项有价值的功能吗?
感谢和最好的问候, 大卫
【问题讨论】:
-
与您的实际问题无关,但使用
return res;,而不是return std::move(res);。前者允许NRVO,如果 NRVO 由于某种原因没有被使用,它仍然会隐式移动,从不复制。 -
另外,
std::move肯定会返回Vector<T>&&,但是您的返回类型声明为Vector<T>? -
@Eric 不,那部分是正确的。返回
Vector<T>&&意味着返回一个对函数本地对象的引用,该对象在函数返回后不能再使用。 -
由于
Vector<T>的邪恶特化,这 2 个计算类型在 sn-p 2 中可能不同。计算类型的第三种方法是std::common_type<T, U>
标签: c++ templates c++11 decltype type-deduction