C++ 推断运算符的(模板化)返回类型+;和其他运营商

C++ 推断运算符的(模板化)返回类型+;和其他运营商,c++,templates,operator-overloading,return-type,C++,Templates,Operator Overloading,Return Type,我正在实现一个二维向量,它的坐标可以采用任何算术类型。我想实现一个操作符+操作符,它以类似unsigned x=2l+3.1的方式从上下文推断其返回类型知道+的结果应该是无符号的,因为它被分配给了一个无符号的 到目前为止,我的灵感来自: #包括 #包括 模板 第2类 { std::数组_数据; 公众: //建设者 Vec2(tx,ty):_数据{x,y}{ //操作员 C++中的模板,+/Cuth>操作符超载没有决定其结果的分配方式。C++根本不这样工作。 在许多情况下,可以以稍微不同的方式设计

我正在实现一个二维向量,它的坐标可以采用任何算术类型。我想实现一个
操作符+
操作符,它以类似
unsigned x=2l+3.1的方式从上下文推断其返回类型知道
+
的结果应该是
无符号的
,因为它被分配给了一个
无符号的

到目前为止,我的灵感来自:

#包括
#包括
模板
第2类
{
std::数组_数据;
公众:
//建设者
Vec2(tx,ty):_数据{x,y}{
//操作员

C++中的模板,+/Cuth>操作符超载没有决定其结果的分配方式。C++根本不这样工作。

在许多情况下,可以以稍微不同的方式设计变通方案。首先让
+
操作员确定最佳回报类型:

template<typename TB> // result's coordinates type
auto operator+(const Vec2<TB> v) const
{
    typedef decltype( static_cast<T>(0) + static_cast<TB>(0) ) ret_t;

    return Vec2<ret_t>(_data[0] + v._data[0],
                    _data[1] + v._data[1]);
}

…希望一切顺利。

2l+3.1
的结果是
double
。一个好的编译器应该警告不要将其分配给
unsigned
。另请参见@rustyx,哦,所以它是在double上计算的,然后转换为unsigned?你知道标准中的什么地方会这样说吗?非常感谢。所以我想做是不可能的但这是我的第二个最佳选择,我没有找到一个优雅的方法来实现它,你的很好(如果在某些代码中实际使用,需要一个好的注释,但它很好)。
$ 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;
      |               ^~~
template<typename TB> // result's coordinates type
auto operator+(const Vec2<TB> v) const
{
    typedef decltype( static_cast<T>(0) + static_cast<TB>(0) ) ret_t;

    return Vec2<ret_t>(_data[0] + v._data[0],
                    _data[1] + v._data[1]);
}
template<typename TB>
operator Vec2<TB>() const
{
    return Vec2<TB>(_data[0], _data[1]);
}