如果我们想用不同的类型初始化引用,我们需要将其设置为 const (const type*),以便可以隐式生成临时对象并将引用绑定到 with。或者,我们可以使用右值引用并实现相同的[1]:
右值引用可用于延长临时对象的生命周期(注意,对 const 的左值引用也可以延长临时对象的生命周期,但不能通过它们进行修改):
[...]
样品
情况1
double x = 10;
int &ref = x; //compiler error (expected)
Run Code Online (Sandbox Code Playgroud)
案例2
double x = 10;
const int &ref = x; //ok
Run Code Online (Sandbox Code Playgroud)
案例3
double x = 10;
int &&ref = x; //ok
Run Code Online (Sandbox Code Playgroud)
如果我们尝试对 const 指针(const type* &)做同样的事情,并用非 const 指针(type*)初始化它,与我预期的不同,只有情况 2 有效。为什么情况3会导致编译器错误?为什么没有生成临时文件?
情况1
int x = 10;
int *pX = &x;
const int* &ref = pX; //compiler error (expected)
Run Code Online (Sandbox Code Playgroud)
案例2
int x = 10;
int *pX = &x;
const int* …Run Code Online (Sandbox Code Playgroud) (我是新手,所以说的可能有不准确的地方)
\n在我当前的思维模型中,溢出是一种算术现象(当我们执行算术运算时发生),而隐式转换是一种赋值(初始化与否)现象(当我们对右手的值不进行赋值时发生)适合左侧值。
\n然而,我经常看到“溢出”和“隐式转换”这两个概念可以互换使用,与我的预期不同。例如,来自 learncpp 团队的这段引用,谈论了有符号 int 的溢出和“位不足”:
\n\n\n当我们尝试存储超出类型范围的值时,就会发生整数溢出(通常简称为溢出)。本质上,我们试图存储的数字需要比对象可用的位数更多的位数来表示。在这种情况下,数据会丢失,因为对象没有足够的内存来存储所有内容[1]。
\n
这是关于 unsigned int 的溢出:
\n\n\n如果我们尝试将数字 280(需要 9 位来表示)存储在 1 字节(8 位)无符号整数中,会发生什么情况?答案是溢出 [2]*
\n
尤其是这个,他使用“模换行”:
\n\n\n这里\xe2\x80\x99是思考同一件事的另一种方式。任何大于该类型可表示的最大数字的数字都简单地 \xe2\x80\x9c 包裹 \xe2\x80\x9d (有时称为 \xe2\x80\x9cmodulo 包裹 \xe2\x80\x9d)。255 在 1 字节整数范围内,因此 255 就可以了。然而,256 超出了范围,因此它回绕到值 0。257 回绕到值 1。280 回绕到值 24 [2]。
\n
在这种情况下,据说超出左手限制的赋值会导致溢出,但我希望在这种情况下使用术语“隐式转换”。
\n我看到术语“溢出”也用于其结果超出左侧限制的算术表达式。
\n我想是这样。在参考文献 [3] 的“数值转换 - 积分转换”部分中,对于无符号整数:
\n\n\n[...] 结果值是等于源值模 2^n\n 的最小无符号值,其中 n 是用于表示目标类型的位数 [3]。
\n
对于签名(粗体我的): …
c++ assembly integer-overflow language-lawyer implicit-conversion
情况1
int main() {
int x = 100;
auto lamb_var = [y = x](){
int y = 10;
return y + 1;
};
assert (lamb_var() == 11);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在https://godbolt.org/z/hPPParjnz
MSVC 和 GCC 都接受隐藏 init-capture,而 Clang 则指责复合语句上的 y 重新定义并引发编译器错误。
但是,如果我们删除 init-capture 并进行 simple-capture,则所有编译器都接受 Shadowing:
案例2
int main() {
int x = 100;
auto lamb_var = [x](){
int x = 10;
return x + 1;
};
assert (lamb_var() == 11);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在https://godbolt.org/z/Gs4cadf5e
简单捕获(情况 2)会导致在 …