首页 > 解决方案 > C++ 重载运算符、常量参数还是按值传递?

问题描述

template <typename T>
T operator+(T a, const T& b) {
    a += b;
    return a;
}

template <typename T>
T operator+(const T& a, const T& b) {
    T tmp {a};
    tmp += b;
    return tmp;
}

有什么理由像第二个函数一样将参数作为常量引用传递,而不是像第一个函数那样直接按值传递,因为无论如何您都需要一个临时变量?


编辑1:

我想我应该提一下,这 2 个替代函数仅用于处理带有左值参数的案例,并且我将提供 2 个其他函数来处理带有右值参数的情况,如下所示。

template <typename T>
T operator+(T&& a, const T& b) {
    a += b;
    return std::move(a);
}

template <typename T>
T operator+(const T& a, T&& b) {
    b += a;
    return std::move(b);
}

所以问题的重点是,为什么我需要显式创建一个临时变量(函数 2),而我可以让语言自动为我提供便利(函数 1)?

标签: c++operator-overloadingparameter-passing

解决方案


template <typename T>
T operator+(T a, const T& b) {
    a += b;
    return a;
}

在这里,您正在制作在此处传入的变量a的副本,然后您正在更新副本。这需要创建三个副本,并且您再次按值返回。

template <typename T>
T operator+(const T& a, const T& b) {
    T tmp {a};
    tmp += b;
    return tmp;
}

在这里,您的tmp变量具有局部范围,变量a是 const 引用,因此不允许修改 a 的。你正在返回一个temp的副本,它是一个局部变量。

两者都可以正常工作,但不同之处在于创建的副本数量。您在第一种情况下制作的副本比在第二种情况下要多。

尽管第二个将针对tmp变量进行优化以使用移动语义以减少副本。所以你在第二种情况下会有更快的表现


推荐阅读