假设我在C ++中使用以下3个签名定义了一些函数rax
:
f
这些函数可以共存,因为它们的参数类型不同。
现在我运行以下代码:
void f(int x) {}
void f(int& x) {}
void f(const int& x) {}
在这种特定情况下,C ++如何知道要调用哪个重载函数?在C ++中编写重载函数的一般规则(最佳实践?)是什么,以避免歧义。当前的C ++ 14标准是否指定了任何特定的规则?
答案 0 :(得分:6)
你不能超载:
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&)
答案 1 :(得分:5)
这三个电话都不明确,因此程序不会编译。
f(3);
这可以使用第一次或第三次重载。他们同样好,所以电话不明确。
f(i);
这可以使用第一次,第二次或第三次重载。第二个比第三个好;在可能的情况下,绑定到int&
优先于绑定到const int&
。因此,以这种方式超载cv资格是很好的。但是第一次和第二次重载之间存在歧义。
f(ci);
这可以使用第一次或第三次重载。同样,他们同样好,所以电话是模棱两可的。
该标准精确指定了重载决策的规则。它们非常复杂,因此以一种使读者难以分辨调用哪个重载的方式重载函数是一个坏主意。您可以找到规则here。
答案 2 :(得分:0)
void f(int x){} 该函数将具有该对象的副本,它将是临时的,因此如果您想要修改该值或传递大量数据,请不要使用它。
void f(int& x){} 相同,但通过引用传递,所以它是一种来自c的指针,但你可以像通常的对象一样使用它。您将能够修改它,并且最好传递大量数据,因为编译器没有复制它。
void f(const int& x){} const在参数之前意味着无法修改对象。顺便说一句,你不必在主体中将它声明为const。
我不确定函数调用案例部分所以我不会回答;)