如何理解C++中引用(及std::atomic_ref)的“常量性是浅层的”?
我之前啃std::atomic_ref的文档时,突然卡壳在这么一句话上:
像核心语言中的引用一样,
std::atomic_ref的常量性是浅层的——你完全可以通过一个const std::atomic_ref对象去修改它所引用的那个值。
别急,咱们先从普通引用的例子入手,把这个“浅层常量性”掰明白。
首先得澄清一个点:C++里的普通引用本身是没法被const修饰的——比如int& const ref = x;这种写法是非法的,因为引用一旦绑定到某个变量,就再也不能切换绑定对象了,相当于它“天生自带不可变绑定”。那这里说的引用的“常量性是浅层的”,其实是指:当我们用const修饰引用的目标类型时(比如const int& ref = x;),这个const管的只是“你不能通过ref去修改x”,但它管不了x本身!如果x本身不是const的,你直接写x = 10照样能改它,这就是“浅层”——const只限制了通过引用的操作,没锁住目标本身。
那std::atomic_ref的情况就更好理解了:它本质是个“带原子操作能力的引用对象”。当你给它加const修饰,比如const std::atomic_ref<int> my_aref = x;,这个const只管my_aref这个对象自己的状态——比如你不能让my_aref重新绑定到另一个变量,但它完全管不了它引用的那个x!所以你照样可以调用my_aref.store(100)这种原子操作,直接把x的值给改了。
说白了,这个“浅层常量性”就是:const修饰的是“引用工具”本身(不管是普通引用的使用权限,还是atomic_ref对象本身),而不是它指向的那个真正要操作的值。就像你拿了一把“不能换锁的钥匙(const的引用/atomic_ref)”,钥匙本身不能去开别的锁,但这不影响你用这把钥匙去拧开当前锁里的东西(修改目标值)。
备注:内容来源于stack exchange,提问作者Angle.Bracket

