Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;将单个变量作为引用和常量引用传递_C++ - Fatal编程技术网

C++ c++;将单个变量作为引用和常量引用传递

C++ c++;将单个变量作为引用和常量引用传递,c++,C++,让我们假设有一个函数f,它接收两个变量,一个是引用变量,另一个是常量引用变量 如果我将单个变量作为两个参数传递,则会发生错误: 结果: a: 6 b: 6 代码 void f(内部和a、内部和b) { a=a+1; std::cout这似乎“正常”工作 您已将函数定义为接受两个参数。声明第一个参数是为了指示引用的整数a可以在f()中更改,但b不应更改 这两个参数都是通过引用传递的,您违反了const的使用,因为更改的a也被引用为b 这种行为是我在没有优化的情况下所期望的。(实际存储为m的整数值

让我们假设有一个函数
f
,它接收两个变量,一个是引用变量,另一个是常量引用变量

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

结果:

a: 6
b: 6
代码

void f(内部和a、内部和b)
{
a=a+1;

std::cout这似乎“正常”工作

您已将函数定义为接受两个参数。声明第一个参数是为了指示引用的整数
a
可以在
f()
中更改,但
b
不应更改

这两个参数都是通过引用传递的,您违反了
const
的使用,因为更改的
a
也被引用为
b


这种行为是我在没有优化的情况下所期望的。(实际存储为
m
的整数值在生成输出之前递增。)但是,根据编译器和选项的不同,可能会对此类别名进行不同的处理。在一般情况下,其行为可能未定义。

此代码定义良好,没有问题

代码
const int&b
表示:

  • b
    指的是
    int
  • 表达式
    b
    不能用于修改该
    int
但是,可以通过其他方式修改
int
。例如,通过此处的
a
。在编译
f
时,编译器必须考虑到
a
b
可能都引用同一对象


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

void f(int & __restrict a, const int & __restrict b)
然后,编译器可能编译
f
,假设
&a!=&b
,也就是说,它可能为您的代码输出
6 5
,这将是无声的未定义行为——编译器不需要诊断
\u restrict


在编写一个函数时,如果该函数采用相同类型的多个引用或指针参数(不包括限定条件),或
char
,则必须注意,某些参数可能会与其他参数同名。您可以通过以下方式之一进行传递:

  • 编写代码,以便即使参数别名
  • 包括一个类似于
    if(&a==&b)return;
  • 使用
    \u restrict
    并记录ONU由调用者承担,不允许别名

一种常见的情况是类的重载
运算符=
。此函数需要支持编写
x=x;
,即
*此
可能会别名函数参数。有时,人们通过检查
if(&A==this)来解决此问题return;
,有时他们会忽略该检查,但会设计实现,以便即使它们相等,它仍能工作。

您要查找的术语是。我不确定“警告编译器”是什么意思-编译器完全知道这个问题。毕竟,它生成的代码产生了正确的输出,不是吗?为什么这是一个问题?您传入了一个可以修改的引用和一个不能修改的引用。它们仍然引用相同的数据,您只是无法通过b更改数据。您没有使数据常量只是对的引用数据。@Pemdas,这段代码容易出错。程序员容易出错。。lol@Pemdas将
A
B
视为矩阵运算,将
f
视为矩阵运算。如果用户向其提供相同的矩阵,则函数将失败。例如
inv(A,A)
。如何解决这个问题?那么你的意思是我在编写所有函数时都应该承担这个风险?是的。无论何时通过引用传递值,别名都可能是一个问题,编译器无法始终捕获。在这种情况下,调用例程定义了
m
的实际存储,并通过引用将其作为非引用传递到例程中-常量。@igor提供了一个链接,可以很好地描述这个问题。第一个要点不是:“
b
指的是
const int
”“@CoffeeandCode不,这就是重点。
b
指的是可以存储
int
的存储。该存储可以是
常量,也可以不是
常量。对不起,我的意思是:第一个要点实际上不是:“b指逻辑上
常量
int
”?@CoffeeandCode否不会。引用不能是c.v限定符,因此c.v限定符必须引用引用的类型。
void f(int & __restrict a, const int & __restrict b)