c++将单个变量作为引用和常量引用传递
c++ pass single variable as both reference and const reference
假设有一个函数f
接收两个变量,一个是引用,另一个是常量引用。
如果我同时传递一个变量作为两个参数,就会发生错误:
结果:
a: 6
b: 6
代码
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;
}
这个问题有已知的名字吗?还有,有什么方法可以警告编译器要小心这一点吗?
此代码定义良好,没有问题。
代码const int &b
表示:
b
表示int
- 表达式CCD_ 5可以不用于修改该CCD_
然而,通过其他方式修改CCD_ 7是完全可以的。例如,通过此处的a
。编译f
时,编译器必须考虑到a
和b
可能都引用同一个对象。
一些编译器具有扩展,以指定函数参数(或其他变量)不应别名;例如,在MSVC++2015中,您可以写:
void f(int & __restrict a, const int & __restrict b)
然后编译器可以编译f
,假设&a != &b
,即它可能为您的代码输出6 5
,这将是无声的未定义行为——编译器不需要诊断违反__restrict
当编写一个使用多个相同类型的引用或指针参数(不包括限定)或char
的函数时,您必须注意,某些参数可能会使其他参数别名。您可以通过以下方式之一提交:
- 编写代码,即使参数别名
- 包括类似
if ( &a == &b ) return;
的支票 - 使用
__restrict
并记录调用方有责任不使用别名
出现的一个常见情况是类的重载operator=
。此函数需要支持有人编写x = x;
,即*this
可以对函数参数进行别名。有时人们会通过检查if ( &a == this ) return;
来解决这个问题,有时他们会省略该检查,但会设计实现,使其即使相等也能工作。
这似乎"正常"工作。
您已经将函数定义为接受两个参数。声明第一个参数是为了指示引用的整数a
可以在f()
中更改,但不应更改b
。
这两个参数都是通过引用传递的,您违反了const
的使用,因为更改的a
也被引用为b
。
这种行为是我在没有优化的情况下所期望的。(实际存储为m
的整数值在生成输出之前已递增。)但是,根据编译器和选项的不同,可能会对这种混叠进行不同的处理。在一般情况下,它的行为可能是不明确的。
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 为什么我可以通过引用修改常量返回
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 将常量指针引用绑定到非常量指针
- 通过常量引用传递参数的矩阵模板类
- 按值捕获引用时出现非常量
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么按值传递QStringView比引用常量更快?
- 通过引用常量函数调用另一个类的非常量函数
- 构造常量对象与引用常量对象
- 引用“常量value_type”时出错
- 为什么可以在 for 语句中重新分配引用常量
- 程序反馈:命名循环索引和引用常量数据
- 堆还是栈?在c++中函数调用中引用常量字符串时
- 为什么常量结构数组在按名称引用常量结构时不放在 .rodata 中?
- 为什么编译器允许在函数中发送对迭代器的引用,该函数引用常量迭代器