简体   繁体   English

模板类运算符+重载返回类型

[英]Templated class operator+ overloading return type

I am trying to built a templated num class.我正在尝试构建一个模板化的 num 类。 This class needs to have a public attribute, val , with type T , which is the only templated parameter.这个类需要有一个公共属性val ,类型为T ,这是唯一的模板化参数。 Furthermore if one provides a value the attribute ( val ) should be initialized with this value.此外,如果提供了一个值,则属性 ( val ) 应使用该值进行初始化。 To do so I made the following code:为此,我编写了以下代码:

#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;
    }
};

Furthermore I created the main() function to test the program, which looks like this:此外,我创建了main()函数来测试程序,它看起来像这样:

int main() {
    std::cout << Num<int>(1) + Num<double>(2.0);
    return 0;
}

However the result of the program is now 3 .然而,程序的结果现在是3 Whereas I expected it to be 3.0 (of type double ).而我预计它是3.0 (类型为double )。

For that you will need to change the return type.为此,您需要更改返回类型。

In your code:在您的代码中:

// vvv---- Means Num<T>
   Num operator+(const Num<U>& other) {
       return val + other.val;
   }

Indeed, inside a class template, you can type the name of the class without template arguments and it's gonna be somewhat equivalent to writing Num<T> .实际上,在类模板中,您可以键入不带模板参数的类的名称,这在某种程度上相当于编写Num<T>

Your function is always returning the type of the first operant, no matter the type of the addition itself.无论加法本身的类型如何,您的函数始终返回第一个操作数的类型。

What you want is to deduce that type coming from the addition:您想要的是从添加中推断出该类型:

auto operator+(const Num<U>& other) -> Num<decltype(val + other.val)> {
    return val + other.val;
}

That way, it's always the right return type according to the C++ operator rules.这样,根据 C++ 运算符规则,它始终是正确的返回类型。

operator+ should be symmetric with respect to its arguments. operator+应该关于它的参数是对称的。 It's better be implemented as a free function rather than a member function to make this symmetry explicit.最好将其实现为自由函数而不是成员函数,以使这种对称性明确。

For example (using C++14 return type deduction):例如(使用 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};
}

std::declval<T>() is there for genericity , if T and/or U are not default constructible.如果T和/或U不是默认可构造的,则std::declval<T>()用于泛型 If types are limited to built-in ones, like int and double , it can be replaced with T{} or T() :如果类型仅限于内置类型,例如intdouble ,则可以将其替换为T{}T()

using R = decltype(T{} + U{});

With class template argument deduction in C++17 it can be simplified further:使用 C++17 中的类模板参数推导,它可以进一步简化:

template<class T, class U>
auto operator+(const Num<T>& x, const Num<U>& y) {
    return Num{x.val + y.val};
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM