C++函数重载分辨率,涉及按值传递、引用和常量引用
C++ function overloading resolution involving pass-by-value, reference and constant reference
假设我在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。
我不确定函数调用案例部分,所以我不会回答这个问题;)
- 何时应通过引用传递矢量参数而不是按值传递矢量参数?
- 棘手的按值传递和按引用递归问题传递
- 不同于按值传递和常量引用传递的程序集
- 按值传递变量与按引用传递变量具有相同的结果
- 为什么按值传递QStringView比引用常量更快?
- 获取 std::函数以推断按引用传递/按值传递
- C++/11 auto 关键字是在更有效时推导参数进行按引用传递,还是始终按值传递?
- 使用 enable_if 在按值传递与按引用传递之间更改函数声明
- C++按引用传递还是按值传递?
- 可移动但不可复制的对象:按值传递还是按引用传递?
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 按引用或值传递链表对象更好吗?
- C++/ASM:按值传递使用 xmm0,但按引用使用 rdi
- 通过查看程序集来比较按值传递与按引用传递性能
- 通过引用传递基元类型(如 int、bool)是否比按值传递有任何加速?还是会恶化时间/空间的使用
- 按值传递的参数在 Visual Studio 2010, C++ 的调试器中显示为通过引用传递
- 引用成员到构造函数参数按值传递
- 为什么功能程序的规律性允许按值传递和按常量引用传递?
- C++ 不可变的自定义类按引用或值传递
- 为什么按值传递 int 比按引用传递更快