我有一个简单的问题:据我所知,我可以声明指向某个数据类型的const
指针或常量数据类型的指针,但是我只能声明对常量数据类型的引用,而不能声明对数据类型的常量引用;引用已经是常量,因为它不能反弹到另一个对象这一事实。
因此,当我尝试创建const ref to someDataType
时,会出现编译时错误。但是最重要的是与type alias
或typedef
一起与using
一起使用时。例如:
#include <iostream>
int main() {
int i{ 10 };
// int& const r1{ i }; // error: ‘const’ qualifiers cannot be applied to ‘int&’. Ok here.
using rInt = int&; // or typedef int& rInt;
const rInt r2{ i }; // why const is allowed here?
++r2; // this proves that the const is applied to the reference not to the object referred to.
std::cout << r2 << std::endl; // 11
}
正如您在上面看到的那样,我可以将const
添加到我认为在那种情况下是多余的引用中。但是,为什么C ++允许使用类型别名而不是直接使用别名呢?
答案 0 :(得分:12)
因为标准是这样说的:
[dcl.ref] ... Cv限定的引用格式不正确,除非通过使用typedef名称([dcl.typedef],[temp.param])或decltype引入cv限定符时-specifier([dcl.type.simple]),在这种情况下,cv限定符将被忽略
这类似于您无法声明引用引用的方式,但是可以通过typedef(其中引用折叠成一个)来实现:
int i;
int& iref = i;
//int& & irefref = iref; // not OK
using Iref = int&;
Iref& iretypedef = iref; // OK; collapses into int&
CV折叠规则,就像引用折叠规则一样,对于使模板和类型推论变得可用至关重要。
答案 1 :(得分:5)
这是常识发挥作用的情况。由于无法重新分配引用,因此它们的作用就像const
。将const
添加到引用声明不会添加任何内容,因此[dcl.ref]/1
T & const
[...] Cv限定的引用格式不正确,除非通过使用typedef名称([dcl.typedef],[temp.param])或decltype-specifier引入cv限定符时( [dcl.type.simple]),在这种情况下,cv限定词将被忽略。
您会注意到,虽然允许使用,但是引用是 typedef-name 或 decltype-specifier 。因此,如果T
为T&
,则const
被忽略。如果不是这样,它将使通用编程更加困难。