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);
}

对象在const为const的范围内进行变异.我知道编译器不能在不证明x和y是别名的情况下强制执行constness.我想我正在寻找的是确认这是未定义的行为.它在某种意义上是否与const_cast相同 – 在一个上下文中使用一个值作为非const?

最佳答案
对const的引用或指针并不意味着根本不能修改引用的对象 – 它只是意味着无法通过此引用/指针修改对象.它可以通过另一个指向同一对象的引用/指针进行修改.这叫做aliasing.

这是一个不使用lambdas或任何其他花哨功能的示例:

int x = 0;

void f() { x = 42; }

void g(const int& y) {
  cout << y;
  f();
  cout << y;
}

int main() {
  g(x);
}

没有任何未定义的内容,因为对象本身不是const,而别名上的constness主要是为了用户的利益.为了彻底,相关部分是[dcl.type.cv] p3:

A pointer or reference to a cv-qualified type need not actually point
or refer to a cv-qualified object, but it is treated as if it does; a
const-qualified access path cannot be used to modify an object even if
the object referenced is a non-const object and can be modified
through some other access path
. [ Note: Cv-qualifiers
are supported by the type system so that they cannot be subverted without casting (5.2.11). —end note ]

转载注明原文:c 11 – 捕获参考的常数 - 代码日志