C++函数重载分辨率,涉及按值传递、引用和常量引用

C++ function overloading resolution involving pass-by-value, reference and constant reference

本文关键字:引用 按值传递 常量 函数 重载 分辨率 C++      更新时间:2023-10-16

假设我在C++中定义了具有以下 3 个签名的函数f

void f(int x) {}
void f(int& x) {}
void f(const int& x) {}

这些函数可以共存,因为它们在参数类型上有所不同。

现在我运行以下代码:

int main {
   int i = 3;
   const int ci = 4;
   f(3);
   f(i);
   f(ci);
}

C++如何知道在这种特定情况下要调用哪个重载函数?一般(最佳实践?)的规则是什么,用于编写重载函数以避免歧义C++。当前的C++14标准是否规定了任何具体规则?

所有三个调用都是不明确的,因此程序不会编译。

f(3);

这可以使用第一个或第三个重载。它们同样好,所以调用是模棱两可的。

f(i);

这可以使用第一个、第二个或第三个重载。第二个比第三个好;如果可能,绑定到int&比绑定到const int&更可取。因此,以这种方式超载简历资格是可以的。但是第一次和第二次重载之间存在歧义。

f(ci);

这可以使用第一个或第三个重载。同样,它们同样好,所以调用是模棱两可的。


该标准精确规定了过载解决的规则。它们非常复杂,因此重载函数的方式使读者难以分辨将调用哪个重载是一个坏主意。您可以在此处找到规则。

不能重载:

void f(int x) {}
void f(const int& x) {}

鉴于这些,编译器将无法消除以下调用的歧义:

f(10);

您不能重载:

void f(int x) {}
void f(int& x) {}

鉴于这些,编译器将无法消除以下调用的歧义:

int i = 0;
f(i);

您可以重载:

void f(int& x) {}
void f(int const& x) {}

鉴于这些,您可以使用:

int i = 0;
f(i);    // Resolves to f(int&)
f(10);   // Resolves to f(int const&)

void f(int x) {}该函数将具有对象的副本,它将是临时的,因此如果要修改值或传递大量数据,请不要使用它。

void f(int& x) {}相同但通过引用传递,因此它是来自 c 的指针,但您可以像使用普通对象一样使用它。您将能够修改它,最好传递大量数据,因为编译器没有太多副本。

在参数之前 void f(const int&x) {} const 表示对象不能被修改。顺便说一下,您不必在主目录中将其声明为 const。

我不确定函数调用案例部分,所以我不会回答这个问题;)