以下是代码示例。
a. int ii = 0;
b. const int ci = ii;
c. auto e = &ci; --> e is const int *
d. auto &f = 42; --> invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
e. const auto &g = 42 --> ok
观察:
1.对于条款c)类型const是自动推导的
2.对于条款d)类型const不是自动推导的
3.对于子句e),必须手动添加const类型才能使其工作。
为什么会自动推导出类型const而不是d?
答案 0 :(得分:7)
原因不是常数,而是r值。
您不能对r值采用非const引用。
如果你想知道什么是r值,那么最初的想法只能在作业的右侧。
要获取编译时常量的地址,编译器首先复制它,并为您提供该地址。要启用该行为,引用必须明确为> library(bigmemory)
Loading required package: bigmemory.sri
Loading required package: BH
bigmemory >= 4.0 is a major revision since 3.1.2; please see packages
biganalytics and and bigtabulate and http://www.bigmemory.org for more information.
> x <- big.matrix(5, 2, type="integer", init=0,
+ dimnames=list(NULL, c("alpha", "beta")))
> saveRDS(x, "bigmem-test.RDS")
> y <- readRDS("bigmem-test.RDS")
> y
An object of class "big.matrix"
Slot "address":
<pointer: (nil)>
> print(y[])
*** caught segfault ***
address 0x51, cause 'memory not mapped'
Traceback:
1: .Call("GetMatrixAll", x@address)
2: GetAll.bm(x)
3: .local(x, ...)
4: y[]
5: y[]
Possible actions:
1: abort (with core dump, if enabled)
2: normal R exit
3: exit R without saving workspace
4: exit R saving workspace
Selection: 3
。
要完成答案: 情况下
const
的类型为ci
,因此const int
的类型为&ci
的地址。const int
的类型为42
。 int
auto
推断为int
,f
被声明为对int
的引用,但无法绑定到r值g
的类型是const int &
,它可以绑定到编译时常量。答案 1 :(得分:1)
这是因为42
的类型不是const int
,而是int
。它是一个rvalue,这意味着它不能绑定到左值引用(除非它是对const
的引用),但它仍然是int
类型。这就是auto
推断出的内容。
如果您使用ci
代替42
进行试用,则会发现works:
auto &e = ci;
答案 2 :(得分:0)
在
auto &f = 42;
42
的类型为int
,因此auto &f
变为int &f
。现在42
是一个编译时文字,因此它是一个r值。我们无法将r值绑定到引用,因此您会收到编译器错误。当你使用
const auto &g = 42
g
现在是const int &
,const &
可以绑定到临时用户并延长其生命周期。
答案 3 :(得分:0)
我认为你对发生的事情有一点混淆。您的c不会尝试推断有关const
的任何内容。 ci
是const int
(int是const)。 &ci
是const int *
(指向int的非const指针,它是const)。自动不能只是int *
,因为那样你就会破坏const契约。
正如其他人所提到的那样,对于d,你试图将非const引用绑定到rvalue(数字'42'不一定存在于内存中,因此你怎么能形成对它的引用..你将来可以修改哪些?)。对于e,编译器现在愿意将42放在内存中,因为你只是承诺你不会改变它。