首页 > 解决方案 > 为什么对引用的 const 引用会失去其 const 性?

问题描述

鉴于此代码:

#include <iostream>

template<typename T>
void modify(const T &j){ j = 42; } // j has type int&

int main()
{
    int i = 10;
    modify<int&>(i); // T=int&
    std::cout << i;  // 42 is printed
}

为什么const T &j变成int &jif T=int&?会发生什么const

标签: c++language-lawyer

解决方案


没有引用引用这样的事情,即没有T & &.

给定const T&where Tis int&,类型会折叠成int&

常量会发生什么?

也不存在 const 引用之类的东西,即不存在T & const(不要与对 const 的引用混淆,后者确实存在,并且通常通俗地称为 const 引用)。不能修改引用(这与修改引用的对象不同),因此 const 没有意义。const 在这里被简单地忽略了。

标准规则(来自最新草案):

[dcl.ref] 如果 typedef-name ([dcl.typedef], [temp.param]) 或 decltype-specifier ([dcl.type.simple]) 表示类型 TR 是对类型 T 的引用,尝试创建类型“对 cv TR 的左值引用”会创建类型“对 T 的左值引用”,而尝试创建类型“对 cv TR 的右值引用”会创建类型 TR。[ 注意:此规则称为参考折叠。——尾注]

这里 cv 指的是 cv 限定符,即 const 和 volatile。

澄清为什么这适用于模板参数:

[temp.param] 标识符不跟在省略号后面的类型参数将其标识符定义为 typedef-name ...


PS 指定引用折叠的方式是完美转发工作的部分原因。


推荐阅读