我一定是误解了auto c++11和以后的解析类型的方式。我有以下代码:
void foo(int& x)
{
++x;
}
int main()
{
int i = 2;
int& ir = i;
long L = 5;
auto a = ir/L;
foo(a);
return 0;
}这将导致编译器错误:
test.cpp: In function 'int main()':
test.cpp:12:10: error: invalid initialization of non-const reference
of type ‘int&’ from an rvalue of type ‘int’
foo(a);
^
test.cpp:1:6: note: initializing argument 1 of ‘void foo(int&)’
void foo(int& x)
^~~但是,将auto替换为int (int a = ir/L;)可以很好地编译,并给出预期的结果(调用foo()之前的a == 0,以及之后的a == 1 )。在浏览了代码并看到了各种错误消息之后,我认为auto被推导为long int&。定义函数void bar(int x)和void bar(const int& x)会导致错误消息:call of overloaded ‘bar(long int&)’ is ambiguous。
评论中的更正:
我不明白auto x = [int&]/[int]如何产生一个可以由非const传递的lvalue,而auto x = [int&]/[long]则导致一个不能传递的rvalue。
发布于 2016-12-14 10:02:14
ir/L的结果是long。对于算术算子,当二进制运算符有不同的类型时,生成的结果将是公共类型;在int和long之间,结果将是long。
所以auto a = ir/L;,a的类型是long。它不能传递给foo(int&),因为您不能将lvalue引用绑定到具有不同类型的非const。
另一方面,如果L的类型是int,那么对于auto a = ir/L;,a的类型将是int,那么一切都很好。
关于“错误的rvalue部分”,当您将一个long传递给foo(int&)时,编译器首先会尝试将它转换为int,这是一个临时的(即rvalue),不能绑定到对非const的值引用。
long可以隐式转换为int,临时可以绑定到对const的lvalue引用,因此将long变量传递给bar(int x)和bar(const int&)都很好。
顺便说一句:当您编写int a = ir/L;时,long类型的结果被隐式转换为int。因此,您将得到一个int,然后把它传递给foo(int&)是可以的。
发布于 2016-12-14 10:03:31
您使用过auto这一事实与此无关。
由于参数提升的规则,a是一种long类型。
因为foo通过引用获取参数,所以编译失败,因为int&不能绑定到long类型(即使它们大小相同并且具有相同的补码表示)。
https://stackoverflow.com/questions/41139522
复制相似问题