以 const 引用作为参数的函数可以更改底层对象吗?

问题描述 投票:0回答:1

对非常量变量的常量引用可以转换为非常量引用,然后可以通过该引用修改底层对象。 它也适用于函数声明中的 const 引用吗?

也就是说,在下面的代码中,如果“a”原本不是 const,那么 func() 是否允许更改“a”? 或者这会导致未定义的行为?

void func(const int& arg);

int main()
{
   int a = 5; //non-const
   func(a);
   std::cout << a; //Can func modify 'a' through a const-cast and thus output ≠5?
}

我问这个问题是因为这会阻止编译器进行优化,因为在计算 func 后它被迫再次查找“a”的值;特别是当 func 的定义在另一个翻译单元中时。

c++ reference constants parameter-passing
1个回答
3
投票

是的,可以。

致电

func
将会做出一个带有“不必要”的参考
const
:

对 cv 限定类型的指针或引用实际上不需要指向或引用 cv 限定对象,但它会被视为指向或引用; [...]

- [dcl.type.cv] p3

func
可以用
const
去除这个“不必要的”
const_cast
:

void func(const int& arg) {
    int& evil = const_cast<int&>(arg); // OK so far
    evil = 123; // undefined behavior only if arg refers to a const object
}

在这种情况下,

func
可以通过
a
修改
evil
,因为
a
不是一个const对象。但是,如果
a
实际上是
const
,那么这将是未定义的行为:

任何在其生命周期内修改 const 对象的尝试都会导致未定义的行为。

- [dcl.type.cv] p4

一般来说,如果给一个函数一个引用或指针,它可以简单地

const_cast
reinterpret_cast
来引用它想要的任何类型。但是,如果访问的对象类型与引用的对象类型不同,则在大多数情况下会导致未定义的行为。 访问权限可能未定义
const_cast
reinterpret_cast
本身就可以。

© www.soinside.com 2019 - 2024. All rights reserved.