C++11 从 int& 和 long 的算术运算中自动推导类型
C++11 auto type deduction from arithmetic operation on int& and long
我一定是误解了 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;
) 可以很好地编译并给出预期的结果(a == 0
在调用 foo()
之前,并且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]
如何导致左值可以通过非常量引用传递,而 auto x = [int&]/[long]
导致右值不能。
ir/L
的结果是long
。对于arithmetic operator,当二元运算符有不同的类型时,产生的结果将是共同的类型;在 int
和 long
之间它将是 long
.
所以auto a = ir/L;
,a
的类型是long
。它不能传递给 foo(int&)
因为你不能将左值引用绑定到不同类型的非常量。
另一方面,给定 L
的类型是 int
,那么对于 auto a = ir/L;
,a
的类型将是 int
,那么一切都很好。
关于"the rvalue part of the error",当你将long
传递给foo(int&)
时,编译器首先会尝试将其转换为int
,这是一个临时的(即一个右值)并且不能绑定到对非常量的左值引用。
long
可以隐式转换为 int
,临时可以绑定到对 const 的左值引用,因此将 long
变量传递给 bar(int x)
和 bar(const int&)
没问题。
顺便说一句:当你写 int a = ir/L;
时,类型 long
的结果被隐式转换为 int
。所以你会得到一个 int
然后把它传递给 foo(int&)
.
就可以了
您使用过 auto
的事实无关紧要。
a
是 long
类型,因为参数提升的规则。
因为 foo
通过引用获取参数 ,编译失败,因为 int&
无法绑定到 long
类型(即使它们大小相同,补码表示相同)。
我一定是误解了 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;
) 可以很好地编译并给出预期的结果(a == 0
在调用 foo()
之前,并且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]
如何导致左值可以通过非常量引用传递,而 auto x = [int&]/[long]
导致右值不能。
ir/L
的结果是long
。对于arithmetic operator,当二元运算符有不同的类型时,产生的结果将是共同的类型;在 int
和 long
之间它将是 long
.
所以auto a = ir/L;
,a
的类型是long
。它不能传递给 foo(int&)
因为你不能将左值引用绑定到不同类型的非常量。
另一方面,给定 L
的类型是 int
,那么对于 auto a = ir/L;
,a
的类型将是 int
,那么一切都很好。
关于"the rvalue part of the error",当你将long
传递给foo(int&)
时,编译器首先会尝试将其转换为int
,这是一个临时的(即一个右值)并且不能绑定到对非常量的左值引用。
long
可以隐式转换为 int
,临时可以绑定到对 const 的左值引用,因此将 long
变量传递给 bar(int x)
和 bar(const int&)
没问题。
顺便说一句:当你写 int a = ir/L;
时,类型 long
的结果被隐式转换为 int
。所以你会得到一个 int
然后把它传递给 foo(int&)
.
您使用过 auto
的事实无关紧要。
a
是 long
类型,因为参数提升的规则。
因为 foo
通过引用获取参数 ,编译失败,因为 int&
无法绑定到 long
类型(即使它们大小相同,补码表示相同)。