8 c++ templates class operator-overloading
我正在尝试构建一个模板化的 num 类。这个类需要有一个公共属性 ,val
和 type T
,这是唯一的模板化参数。此外,如果提供了一个值,则属性 ( val
) 应使用该值进行初始化。为此,我编写了以下代码:
#include <iostream>
template<class T>
class Num {
public:
T val;
Num():val(0) { std::cout<<"default constr used"<<std::endl; }
Num(T value):val(value) {std::cout<<"constr (T value) used"<<std::endl; }
~Num() { std::cout<<"destructor used"<<std::endl; }
template<typename U>
Num operator+(const Num<U>& other) {
return val+other.value;
}
};
Run Code Online (Sandbox Code Playgroud)
此外,我创建了main()
测试程序的函数,如下所示:
int main() {
std::cout << Num<int>(1) + Num<double>(2.0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而,程序的结果是现在3
。而我期望它是3.0
(类型double
)。
Gui*_*cot 10
为此,您需要更改返回类型。
在您的代码中:
// vvv---- Means Num<T>
Num operator+(const Num<U>& other) {
return val + other.val;
}
Run Code Online (Sandbox Code Playgroud)
实际上,在类模板中,您可以键入不带模板参数的类的名称,这有点等同于编写Num<T>
.
无论加法本身的类型如何,您的函数始终返回第一个操作数的类型。
您想要的是从添加中推断出该类型:
auto operator+(const Num<U>& other) -> Num<decltype(val + other.val)> {
return val + other.val;
}
Run Code Online (Sandbox Code Playgroud)
这样,根据 C++ 运算符规则,它始终是正确的返回类型。
operator+
应该关于它的参数是对称的。最好将其实现为自由函数而不是成员函数,以使这种对称性明确。
例如(使用 C++14 返回类型推导):
template<class T, class U>
auto operator+(const Num<T>& x, const Num<U>& y) {
using R = decltype(std::declval<T>() + std::declval<U>());
return Num<R>{x.val + y.val};
}
Run Code Online (Sandbox Code Playgroud)
std::declval<T>()
是否存在通用性,如果T
和/或U
不是默认可构造的。如果类型仅限于内置类型,例如int
and double
,则可以替换为T{}
or T()
:
using R = decltype(T{} + U{});
Run Code Online (Sandbox Code Playgroud)
使用C++17 中的类模板参数推导,它可以进一步简化:
template<class T, class U>
auto operator+(const Num<T>& x, const Num<U>& y) {
return Num{x.val + y.val};
}
Run Code Online (Sandbox Code Playgroud)