为什么我可以使用类型别名声明const引用?

时间:2019-01-31 20:22:01

标签: c++ reference

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

因此,当我尝试创建const ref to someDataType时,会出现编译时错误。但是最重​​要的是与type aliastypedef一起与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 ++允许使用类型别名而不是直接使用别名呢?

2 个答案:

答案 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 。因此,如果TT&,则const被忽略。如果不是这样,它将使通用编程更加困难。

相关问题