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

Mut*_*thm 3 c++ overloading

假设我f在C++中使用以下3个签名定义了一些函数:

void f(int x) {}
void f(int& x) {}
void f(const int& x) {}
Run Code Online (Sandbox Code Playgroud)

这些函数可以共存,因为它们的参数类型不同.

现在我运行以下代码:

int main {
   int i = 3;
   const int ci = 4;

   f(3);
   f(i);
   f(ci);
}
Run Code Online (Sandbox Code Playgroud)

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

R S*_*ahu 6

你不能超载:

void f(int x) {}
void f(const int& x) {}
Run Code Online (Sandbox Code Playgroud)

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

f(10);
Run Code Online (Sandbox Code Playgroud)

你不能超载:

void f(int x) {}
void f(int& x) {}
Run Code Online (Sandbox Code Playgroud)

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

int i = 0;
f(i);
Run Code Online (Sandbox Code Playgroud)

你可以超载:

void f(int& x) {}
void f(int const& x) {}
Run Code Online (Sandbox Code Playgroud)

鉴于这些,您可以使用:

int i = 0;
f(i);    // Resolves to f(int&)
f(10);   // Resolves to f(int const&)
Run Code Online (Sandbox Code Playgroud)


Bri*_*ian 5

这三个调用都是模棱两可的,因此该程序无法编译。

f(3);
Run Code Online (Sandbox Code Playgroud)

这可以使用第一或第三重载。它们同样好,因此通话是模棱两可的。

f(i);
Run Code Online (Sandbox Code Playgroud)

这可以使用第一,第二或第三重载。第二个比第三个好。绑定到int&优先于绑定到(const int&如果可能)。因此,以这种方式重载cv-qualification很好。但是第一次和第二次重载之间存在歧义。

f(ci);
Run Code Online (Sandbox Code Playgroud)

这可以使用第一或第三重载。同样,它们同样好,因此调用是不明确的。


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