捕获参考的常数

scr*_*cry 7 const c++11

可以通过可变引用捕获对象,并在成员函数内部进行更改,该成员函数采用相同的对象const.

void g(const int& x, std::function<void()> f)
{
  std::cout << x << '\n';
  f();
  std::cout << x << '\n';
}

int main()
{
  int y = 0;
  auto f = [&y] { ++y; };
  g(y, f);
}
Run Code Online (Sandbox Code Playgroud)

对象在其所在的范围内发生变异const.据我所知,编译器不能在这里执行常量性不证明xy是别名.我想我正在寻找的是确认这是未定义的行为.在某种意义上它是否等同于const_cast- const在一个应该存在的上下文中使用非值?

Igo*_*nik 4

指向 const 的引用或指针并不意味着根本无法修改引用的对象 - 它只是意味着无法通过此引用/指针修改该对象。它很可能通过同一对象的另一个引用/指针进行修改。这称为别名

\n\n

这是一个不使用 lambda 或任何其他奇特功能的示例:

\n\n
int x = 0;\n\nvoid f() { x = 42; }\n\nvoid g(const int& y) {\n  cout << y;\n  f();\n  cout << y;\n}\n\nint main() {\n  g(x);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

没有什么未定义的事情发生,因为对象本身不是const,并且别名的常量性主要是为了用户的利益。为了彻底起见,相关部分是[dcl.type.cv]p3

\n\n
\n

对 cv-quali\xef\xac\x81ed 类型的指针或引用实际上不需要指向\n或引用 cv-quali\xef\xac\x81ed 对象,但它被视为好像它确实指向或引用;a\n const-quali\xef\xac\x81ed 访问路径不能用于修改对象,即使\n 引用的对象是非常量对象并且可以通过其他访问方式修改\xef\xac\x81ed\n小路。[ 注意: Cv-quali\xef\xac\x81ers\n 受类型系统支持,因此如果不进行强制转换 (5.2.11),它们就无法被破坏。\xe2\x80\x94结束注]

\n
\n