gpt4 book ai didi

c++ - 常量和非常量引用绑定(bind)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:35:21 27 4
gpt4 key购买 nike

void swap(int& a, int& b) {}

void copy(int& a, const int& b) {}

int main() {
int a=1;
unsigned b=2;

swap(a, b);
copy(a, b);
}

C++ 语言,g++ 编译器。

请告诉我为什么在copy函数调用中不会出现编译错误,但在swap -函数触发 从类型为“unsigned int”的表达式对类型为“int&”的引用的无效初始化

抱歉我的英语不好。

最佳答案

短篇小说

首先 - 规则 L 用于将具有限定条件 cv2U 类型的表达式引用绑定(bind)到具有 T 类型的引用资格cv1.:

A reference to cv1 T can be initialized by an expression of type cv2 U

  • if the reference is an lvalue reference and the initializer expression

    • is an lvalue and cv1 T is reference-compatible with cv2 U, or
    • has a class type [ ... ].
  • Otherwise, cv1 shall be const or the reference shall be an rvalue reference.

cv1 T is reference-compatible to cv2 U if T is the same types as U (or a base of U) and if cv1 is equal to cv2(or greater).

不幸的是(或幸运的是?!;))不能使用非引用兼容类型的左值调用具有非常量左值引用参数的函数(或者在类类型没有传递的可行转换的情况下)引用兼容类型的参数)。

详细

让我们考虑一个接受整数引用的函数和另一个具有常量整数引用参数的函数。

void doSomething (int & x)
{
// do some READ & WRITE stuff with x
x = x+5;
}

int doSomethingElse (int const & x)
{
// do some READ ONLY stuffwith x
return 3*x;
}

让我们看看一个有符号的值和另一个无符号的值:

 int a = 1;
unsigned int b = 2;

现在我们将名为aint 传递给doSomething():

 // works since x of doSomething can bind to a
doSomething(a);

// let's try to expand/"inline" what is happening
{
int & x = a;
x = 5;
}

这里没有魔法,引用 x 绑定(bind)到 a 并设置为 5(因此 a 也设置为 5)。很好。

现在我们尝试将 b 传递给同一个函数。但是……

   // ... it doesn't work/compile since
// unsigned int is not reference compatible to int
doSomething(b); // compile error here

// what's going on here
{
int & x = b; // unsigned value cannot bind to a non-const lvalue reference!
// compile error here
x = 5;
}

这里我们开始遇到麻烦,使用 b 调用 doSomething 将无法编译。

现在让我们看一下常量引用函数。传 a 显然又没有问题了。 const int 引用绑定(bind)到 int 值。

int c = doSomethingElse(a);

// let's do some naive inlining again
int c;
{
int const & x = a;
c = 3*x;
}

嗯,看起来不错。 c 将是 3*a

现在如果我们将 b 传递给那个函数会发生什么?该标准规定,在这种情况下,将使用复制初始化规则从初始化表达式创建并初始化 cv1 T 类型的临时对象。

int d = doSomethingElse(b);

// expanding this to:
int d;
{
int temp = b; // implicit conversion, not really an lvalue!
int const & x = temp;
d = 3*x;
}

关于c++ - 常量和非常量引用绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17256007/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com