为什么我可以使用类型别名声明常量引用

Why I can declare a const reference using type-alias?

本文关键字:声明 常量 引用 别名 类型 我可以 可以使 为什么      更新时间:2023-10-16

我有一个简单的问题:据我所知,我可以声明一个指向某个数据类型的const指针或一个指向常量数据类型的指针,但我只能声明对常量数据类型的引用,而不能声明对数据类型的常量引用;事实上,一个引用已经是常量,因为它不能重新绑定到另一个对象。

因此,当我尝试创建const ref to someDataType时,会出现编译时错误。但对我来说重要的是,当与type alias一起使用时,使用typedefusing。例如:

#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++允许使用类型别名而不是直接这样做呢?

因为标准是这样说的:

[参考资料] ...Cv 限定引用的格式不正确,除非通过使用 typedef-name ([dcl.typedef], [temp.param]) 或 decltype-specifier ([dcl.type.simple]) 引入 cv 限定符,在这种情况下,将忽略 cv 限定符

这类似于不能声明引用引用的方式,而可以通过 typedef(其中引用折叠为一个):

int i;
int& iref = i;
//int& & irefref = iref; // not OK
using Iref = int&;
Iref& iretypedef = iref; // OK; collapses into int&
CV 折叠规则,

就像参考折叠规则一样,对于使模板和类型推断可用至关重要。

这是常识发挥作用的情况。 由于不能重新分配引用,因此它们就像const一样。 向引用声明添加const不会添加任何内容,因此根据 [dcl.ref]/1 禁止T & const

[...] Cv限定引用的格式不正确,除非通过使用typedef-name([dcl.typedef],[temp.param])或decltype-specifier([dcl.type.simple])引入cv限定符,在这种情况下,cv限定符将被忽略。

你会注意到,虽然它是允许的,但引用是一个typedef-namedecltype-specifier。因此,如果T T&则忽略const。 如果不是这样,它将使泛型编程更加困难。