为什么函数参数中的const限定符用于重载解析
Why are const qualifiers in function arguments used for overloading resolution?
可能重复:
带有常量参数和重载的函数
重载和const声明规则让我很困惑。以下是让我困惑的两件事——也许你可以帮助我在脑海中找到更深层次的误解,导致它们让我感到困惑。)
第一期:
我的编译器允许这样做:
void f(int & x) {
std::cout << "plain f" << std::endl;
}
void f(const int & x) {
std::cout << "const f" << std::endl;
}
但是以下情况会导致编译错误(函数已经有了主体):
void f(int x) {
std::cout << "plain f" << std::endl;
}
void f(const int x) {
std::cout << "const f" << std::endl;
}
我认为这是有道理的,因为我认为const只是用来告诉编译器传递的对象没有改变,在第二种情况下,它无论如何都会被复制。但如果这是正确的,那么为什么我可以使用const重载函数呢?
换句话说,为什么我使用编译版本并调用这样的函数:
int x1 = 5;
const int x2 = 5;
f(x1);
f(x2);
我会得到两次"普通f"answers"const f"而不是"const f"吗?显然,现在我还使用const来告诉编译器要调用哪个函数,不仅引用没有改变。这会变得更令人困惑,因为如果我删除"普通"版本,它会正常工作,并调用"const"版本两次。
现在我真正的问题是什么?我想知道这种行为背后的想法是什么,因为否则记住它是非常困难的。
n3337 13.1
[注意:如8.3.5所述,具有等效的参数声明声明相同的函数和因此不能过载:ffer仅在存在或不存在的情况下
--di3的参数声明的const和/或volatile是等效的。也就是说,const和当确定要声明、定义或调用的函数。[示例:
typedef const int cInt; int f(int); int f(const int); // redeclaration of f(int) int f(int) { /* ... */ } // definition of f(int) int f(cInt) { /* ... */ } // error: redefinition of f(int)
--完example]只有最外层的const和volatile类型说明符此中忽略参数类型规范的级别时尚参数中隐藏的const和volatile类型说明符型号规格很重要,可用于区分重载函数声明124特别是对于任何类型T,"指针到T"、"指针到常量T"answers"指针到易失性T"被认为是不同的参数类型,如"对T的引用"引用常量T"answers"引用挥发性T"
我以为const只是用来告诉编译器对象通过的不会更改,在第二种情况下,它无论如何都会被复制
你是对的。因为在第二种情况下,它无论如何都是被复制的,所以const
对调用者没有什么区别,所以标准定义void f(const int x)
和void f(int x)
具有相同的签名。因此,它们发生了碰撞,你试图定义同一个函数两次。
因为在第一种情况下,它无论如何都不是复制的,所以void f(const int &x)
和void f(int &x)
具有不同的签名。因此它们过载。
在第一种情况下,禁止使用x2
作为参数调用f
的int&
版本,因为这将创建对const对象的非常量引用,而看不到任何显式强制转换。这样做违背了const系统的目的(也就是说,如果你想破坏const的安全性,你必须通过强制转换显式地这样做)。因此,对具有引用参数的函数进行常量和非常量重载是有意义的。
在第二种情况下,副本的源的常量和目的地的常量之间没有关系。您可以从非常数变量初始化一个常量变量,也可以从常量变量初始化非常数变量。这不会造成任何问题,也不会破坏const安全性。这就是为什么标准通过定义f
的两个"不同"版本实际上是相同的函数来明确这一点。
- 重载操作程序时出错>>用于类中的字符串 memebr
- 重载==不适用于二进制树
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 如何调用用于重载运算符"<<"的 friend 函数?
- 重载 std::字符串运算符+ 用于打印枚举名称
- 一种优雅或至少可行的方法,用于使用和接受具有重载方法和运算符的不同大小的文字数组常量
- 重载运算符 += 用于 C++ 中的链表
- 隐式生成的函数重载用于右值参数?
- 重载运算符 + 用于向量:命名空间标准
- 重载运算符 [] 用于从对象数组中给出特定索引
- C++ 重载"<<"不适用于输出"obja + objb"
- 用于测量重载运算符和成员函数的时间的函数
- 设置器不适用于重载运算符
- 如何使用 is_invocable() 创建用于重载<<打印对象的模板?
- 用于重载的泛型类成员函数
- C++创建一个标头,其中包含用于重载 ostream 的模板
- 为什么函数参数中的const限定符用于重载解析
- 为什么auto不能用于重载函数
- 对象工厂用于重载函数
- C2440用于重载函数MsgProc