我无法初始化非const 引用以从可转换类型T2中键入T1。但是,我可以使用 const 引用。
long l;
const long long &const_ref = l; // fine
long long &ref = l; // error: invalid initialization of reference of
// type 'long long int&' from expression of type
// 'long int'
我遇到的大多数问题都与无法分配给非const引用的r值有关。这不是这里的情况 - 有人可以解释一下吗?感谢。
答案 0 :(得分:7)
整数提升会产生右值。 long
可以升级为long long
,然后绑定到const引用。就像你做了一样:
typedef long long type;
const type& x = type(l); // temporary!
相反,如你所知,rvalue不能绑定到非const引用。 (毕竟,没有实际的long long
可以参考。)
答案 1 :(得分:1)
long long
的大小不一定等于long
,甚至可能使用完整的不同内部表示。因此,您无法将long
的非const引用绑定到类型为long long
的对象,反之亦然。标准禁止它,你的编译器是正确的,不允许它。
您可以对以下代码段采用相同的方式:
long a = 0;
long long b = 0;
a = b; // works!
long *pa = 0;
long long *pb = pa;
上次初始化无效。仅仅因为一种类型可以转换为另一种类型,并不意味着将其中一种化合物转化为另一种化合物的另一种类型。同样,对于以下情况
struct A { long i; };
struct B { long long i; };
A a;
B b = a; // fail!
在这种情况下,A
和B
分别对long
和long long
类型进行了复合,很像long&
和long long&
这些类型的复合。但是,由于这一事实,它们不会相互转换。其他规则恰好适用。
如果引用是const,则创建一个具有正确类型的临时对象,然后将引用绑定到该对象。
答案 2 :(得分:0)
我不是标准律师,但我认为这是因为long long
比long
宽。允许使用const引用,因为您不会更改l
的值。常规引用可能会导致对l
来说太大的赋值,因此编译器不会允许它。
答案 3 :(得分:0)
我们假设它是可能的:
long long &ref = l;
这意味着稍后在代码中你可以将ref引用的值更改为更大的值,然后long类型可以保持但是很长时间都可以。实际上,这意味着你会覆盖额外的内存字节,这些字节可以被不同的变量用于不可预测的结果。