【问题标题】:Why I can declare a const reference using type-alias?为什么我可以使用类型别名声明 const 引用?
【发布时间】:2019-01-31 20:22:01
【问题描述】:

我有一个简单的问题:据我所知,我可以声明指向某个数据类型的 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++ 允许使用类型别名而不是直接使用呢?

【问题讨论】:

  • 在我的编译器上,我得到了Alex24.cpp:8:5: warning: 'const' qualifier on reference type 'rInt' (aka 'int &amp;') has no effect [-Wignored-qualifiers] ...您是否打开了警告?我认为这与您的问题无关,因为您在问为什么允许 const (即使被忽略)。
  • @FrançoisAndrieux 那为什么我可以通过rInt更改对象呢?
  • 和using t_Value = int const; t_Value const value{};一样,第二次申请const没有效果。但是,您的引用是对可变对象的引用,因此您可以使用该引用更改对象。请注意,将 const 添加到 rInt 不会将引用转换为对 const 限定对象的引用。
  • @Alex24 “但是为什么 C++ 允许使用类型别名而不是直接使用呢?” 我不相信该语言正式禁止它。编辑:对于它的价值r1 在 VC++ 14.0 中产生警告。
  • 您可能想要添加language-lawyer 标签,因为我假设您想要标准中的章节+诗句。

标签: c++ reference


【解决方案1】:

因为标准是这样说的:

[dcl.ref] ... Cv 限定的引用格式错误,除非通过使用 typedef-name ([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 折叠规则,就像参考折叠规则一样,对于使模板和类型推导可用是必不可少的。

【讨论】:

    【解决方案2】:

    这是常识发挥作用的情况。由于无法重新分配引用,它们的行为就好像它们是const。将const 添加到引用声明中不会添加任何内容,因此T &amp; const 禁止[dcl.ref]/1

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

    您会注意到虽然它是允许的,但引用是 typedef-name 或 decltype-specifier。因此,如果 T 是 T&amp; 则 const 将被忽略。如果不是,它将使泛型编程变得更加困难。

    【讨论】:

    • 没有“隐式const”这样的东西,引用也不是const。试试std::is_const_v&lt;int&amp;&gt;
    • 他们的行为也不像const。如果您尝试分配给 const 对象,则会出现错误。该语言甚至不允许尝试重新分配参考。
    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 2014-01-01
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多