【问题标题】:Operator overloading for two different types of same templated class/structure? [duplicate]两种不同类型的相同模板类/结构的运算符重载? [复制]
【发布时间】:2020-01-14 22:44:03
【问题描述】:

我有一个方便的类,Vector。它实际上只是一个包含 3 个东西的模板结构。它们可以是浮点数、双精度数、整数等。

IE:

template <typename T>
struct Vector 
{
 T x;
 T y;
 T z;
}

它有很好的运算符重载,允许我将两个向量相加,例如:

Vector operator+(const Vector& rhs) 
{
 return Vector(x + rhs.x, y + rhs.y, z + rhs.z);
}

但是,如果我想这样做怎么办:

Vector<float> myFloatVec(0.2, 0.5, 0.95);
Vector<int> myIntVec(2, 5, 1);

Vector<float> result = myFloatVec + myIntVec; // cannot do this

如果我以后想更改类型怎么办:

vector<int> result2 = static_cast<int>(result); // cannot do, this would be nice too

有没有办法在 C++ 中轻松完成类似的事情?

如果我能以某种方式将整数向量转换为浮点向量,那么我可以让正常的运算符重载接管。可悲的是,我不知道有什么方法可以重载 static_cast 在类型上的工作方式。

【问题讨论】:

  • 它似乎在正确的轨道上,不知何故错过了它。虽然答案有点令人困惑,因为它似乎并没有真正执行 ```+=``,不确定我是否遗漏了什么。
  • 你的代码没有+=,所以我看不出问题
  • 您可以为特定类型的向量添加另一个重载,即 Vector&lt;T&gt; operator+(const Vector&lt;int&gt;&amp; rhs) 甚至 Vector&lt;T&gt; operator+(const U&amp; rhs)。虽然老实说,我认为我根本不涉及模板,可能只有两种不同的类型,而不是显式命名的函数,任何转换都必须发生。
  • @TylerShellberg 够公平的。可能是回答者的错字。但重点是一样的。不管是++=-还是%=,你的问题出在你的声明上,而不是函数的实际内容。
  • @Chipster:不是回答者的部分;原始问题的示例代码也没有执行类似+= 的操作。但是+= 的主体在很大程度上是无关紧要的;你以任何看起来合理的方式实现它。

标签: c++ c++11 templates overloading


【解决方案1】:

您可以执行以下操作

#include <iostream>
#include<type_traits>

template <typename T>
struct Vector 
{
    T x;
    T y;
    T z;
};

template <typename T1, typename T2>
auto operator +( const Vector<T1> &v1, const Vector<T2> &v2 ) -> Vector<typename std::common_type<T1, T2>::type>
{
    return { v1.x + v2. x, v1.y + v2.y, v1.z + v2.z };  
}

int main() 
{
    Vector<int> v1 = { 1, 2, 3 };
    Vector<float> v2 = { 1.1f, 2.2f, 3.3f };

    Vector<float> v3 = v1 + v2;

    std::cout << "v3.x = " << v3.x 
              << ", v3.y = " << v3.y
              << ", v3.z = " << v3.z 
              << '\n';

    return 0;
}

程序输出是

v3.x = 2.1, v3.y = 4.2, v3.z = 6.3

【讨论】:

  • vector&lt;int&gt; result2 = static_cast&lt;int&gt;(result); 怎么样?
  • 我可能还会使用std::typeof(std::declval&lt;T1&gt;()+std::declval&lt;T2&gt;()) 而不是common_type,以处理任何其他奇怪的重载(又名vector&lt;vector&lt;int&gt;&gt;
  • @MooingDuck 在这种情况下,例如需要模板转换构造函数。
  • @VladfromMoscow 这种方法与仅使用单个参数模板化运算符重载的主要区别是什么,就像人们链接的其他方法一样?
  • @TylerShellberg 通常二元运算符被声明为非类函数。
猜你喜欢
  • 2012-04-26
  • 1970-01-01
  • 2016-06-23
  • 2021-09-15
  • 1970-01-01
  • 2019-06-04
  • 2019-08-05
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多