c ++将单个变量作为引用和const引用传递

ar2*_*015 2 c++

假设有一个函数f通过引用接收两个变量,另一个是常量引用.

如果我将单个变量作为两个参数传递,则会发生错误:

结果:

a: 6
b: 6
Run Code Online (Sandbox Code Playgroud)

void f(int &a,const int &b)
{
    a=a+1;
    std::cout<<"a: "<<a<<"\n";
    std::cout<<"b: "<<b<<"\n";
}

int main()
{
    int m=5;
    f(m,m);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个问题有没有已知的名字?另外,有什么方法可以警告编译器要小心吗?

M.M*_*M.M 5

这段代码定义明确,没有问题.

代码const int &b意味着:

  • b 指的是 int
  • 表达式b可能不会用于修改它int.

然而,int通过其他方式进行修改是完全正确的.例如,通过a这里.编译时f,编译器必须考虑到这一点,a并且b可能都引用同一个对象.


有些编译器有扩展来指定函数参数(或其他变量)不应该别名; 例如,在MSVC++ 2015中,您可以编写:

void f(int & __restrict a, const int & __restrict b)
Run Code Online (Sandbox Code Playgroud)

然后编译器可以编译f假设&a != &b,即它可能6 5为您的代码输出,现在将是静默未定义的行为 - 编译器不需要诊断违反__restrict


当编写一个带有相同类型的多个引用或指针参数(不包括资格)的函数时,或者char,您必须意识到某些参数可能会对其他参数进行别名.您可以通过以下方式之一处理:

  • 编写代码,使其即使参数别名也能正常工作
  • 包括支票 if ( &a == &b ) return;
  • 使用__restrict并记录调用者的责任不是别名.

这显示的一个常见情况是operator=类的重载.此函数需要支持某人编写x = x;,*this即可以为函数参数添加别名.有时人们通过检查来解决这个问题if ( &a == this ) return;,有时他们会省略检查但是设计实现以便即使它们相同也能正常工作.