【发布时间】:2020-02-09 14:13:13
【问题描述】:
我正在实现一个二维向量,它可以采用任何算术类型作为其坐标。我想实现一个operator+ 运算符,它从上下文推断其返回类型,就像unsigned x = 2l + 3.1; 知道+ 的结果应该是unsigned,因为它被分配给unsigned。
到目前为止,我所拥有的灵感来自Templates inferring type T from return type:
#include <array>
#include <type_traits>
template<typename T,
typename = std::enable_if_t<std::is_arithmetic_v<T>, T>>
class Vec2
{
std::array<T, 2> _data;
public:
// Constructors
Vec2(T x, T y): _data{x, y} {}
// Operators
template<typename TB, // second operand's coordinates type
typename TR> // result's coordinates type
Vec2<TR> operator+(const Vec2<TB> v) const
{
return Vec2<TR>(_data[0] + v._data[0],
_data[1] + v._data[1]);
}
};
int main(void)
{
Vec2 vi{0, 2};
Vec2 vf{1.4, 2.2};
Vec2<int> res = vi + vf;
}
我得到一个错误,说它无法推断出用于返回值的类型:
$ g++ -Wall -Wextra -std=c++17 poc.cc
poc.cc: In function ‘int main()’:
poc.cc:29:24: error: no match for ‘operator+’ (operand types are ‘Vec2<int, int>’ and ‘Vec2<double, double>’)
29 | Vec2<int> res = vi + vf;
| ~~ ^ ~~
| | |
| | Vec2<double,double>
| Vec2<int,int>
poc.cc:17:14: note: candidate: ‘template<class TB, class TR> Vec2<TR> Vec2<T, <template-parameter-1-2> >::operator+(Vec2<TB>) const [with TB = TB; TR = TR; T = int; <template-parameter-1-2> = int]’
17 | Vec2<TR> operator+(const Vec2<TB> v) const
| ^~~~~~~~
poc.cc:17:14: note: template argument deduction/substitution failed:
poc.cc:29:26: note: couldn’t deduce template parameter ‘TR’
29 | Vec2<int> res = vi + vf;
| ^~
poc.cc:29:15: warning: unused variable ‘res’ [-Wunused-variable]
29 | Vec2<int> res = vi + vf;
| ^~~
【问题讨论】:
-
2l + 3.1的结果是double。一个好的编译器应该警告将其分配给unsigned。 -
@rustyx,哦,所以它是在 double 上计算的,然后 然后 转换为无符号的?你知道标准中的哪个地方是这么说的吗?
标签: c++ templates operator-overloading return-type