c++ - 通过非常量引用参数修改常量引用参数

标签 c++ pass-by-reference const-correctness pass-by-const-reference

考虑以下代码:

#include <iostream>

void f(int const& a, int& b)
{
  b = a+1;
}

int main() {
  int c=2;
  f(c,c);
  std::cout << c << std::endl;
}
  • 功能 f接受两个引用参数:int const& aint& b .因此,f不应该修改a , 但可以修改 b ,而且确实如此。
  • 然而,在 main , 我传递了相同的变量,由 a 引用来自 b .如 f修改 b ,它还修改了 a ,它应该不应该

  • 此代码编译时没有任何警告并打印 3 .如果我们单独跟踪每个变量,看起来像 const-正确性:c是非常量的,因此将它作为 const 传递是完全没问题的。引用为 a ,以及作为 b 的非常量引用,并在 f 的正文中我们修改 b ,这是非常量,同时不接触 a ,这是常量。然而,当 c都被用作 a并作为 b , af 的正文中进行了修改,违反了 a 的假设是 const,即使没有明确的 const_cast曾经被称为。

    我尽可能地简化了这个例子,但人们很容易想到不那么明显的用例(例如 const 作用于非常量引用参数的方法)。

    我的问题是:
  • 我们真的可以说上面的代码是常量正确的吗?
  • 上述用例是已知模式吗?这被认为是不好的做法吗?
  • 除了让读者感到困惑之外,上面的代码还能成为技术问题的根源吗?例如未定义的行为,或者编译器执行错误的简化假设?
  • 最佳答案

    However, in main, I pass the same variable, referenced both by a and by b. As f modifies b, it also modifies a, which it supposedly shouldn't



    f修改什么 b指的是,它不修改a .它修改了什么 a指的是,但没关系,因为 b不是 const .只有当您尝试修改什么时才a指使用 a你有问题。

    Can we really say the above code is const-correct?



    是的。您不修改 const 变量。

    Other than being confusing to a reader, can the above code be the source of technical problems? Such as undefined behavior, or the compiler performing wrong simplifying assumptions?



    不,您的代码是合法的,并且会在所有符合标准的编译器上产生相同的结果。

    一个常量引用参数不会使它引用的东西const如果不是 const开始。它所做的一切都会阻止您使用引用来修改对象。另一个指向该对象的指针或引用仍然可以改变它,只要它不是 const本身。

    关于c++ - 通过非常量引用参数修改常量引用参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62390190/

    相关文章:

    C++ : automatic const?

    c++ - 通过引用 cpp 返回字符串

    pass-by-reference - 当我们在此函数中按值传递结果时会发生什么?

    c++ - 当前的标准草案似乎无法解释为什么两个结构化绑定(bind)声明相互冲突

    c++ - 为 DiagonalMatrix 对象重载 operator()

    python - 将生成器附加到循环中的堆栈,生成器指向最终循环变量

    c++ - 如何处理const对象中非const引用成员的初始化?

    c++ - MSVC : C++14: std:set: comparison function: why "const" is required?

    C++ 强制转换语法样式

    c++ - 将一个类的 std::vector 作为同一个类的属性是一个好的设计选择吗?