简体   繁体   English

从int&和long上的算术运算得出的C ++ 11自动类型推导

[英]C++11 auto type deduction from arithmetic operation on int& and long

I must be misunderstanding how auto c++11 and later resolves types. 我一定误会了auto c ++ 11和更高版本如何解析类型。 I have the following code: 我有以下代码:

void foo(int& x)
{
    ++x;
}

int main()
{
    int i = 2;
    int& ir = i;
    long L = 5;
    auto a = ir/L;
    foo(a);

    return 0;
}

This results in the compiler error: 这导致编译器错误:

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)
      ^~~

However, replacing auto with int ( int a = ir/L; ) compiles fine and gives the expected result ( a == 0 before the call to foo() , and a == 1 after). 但是,将auto替换为intint a = ir/L; )可以很好地编译并得到预期的结果(调用foo()之前a == 0之后调用a == 1 )。 After playing around with the code and seeing various error messages, I think auto is deduced to long int& . 在玩完代码并看到各种错误消息之后,我认为auto被推导为long int& Defining the functions void bar(int x) and void bar(const int& x) results in the error message: call of overloaded 'bar(long int&)' is ambiguous . 定义函数void bar(int x)void bar(const int& x)导致错误消息: call of overloaded 'bar(long int&)' is ambiguous

Correction from comments: 来自评论的更正:

I don't understand how auto x = [int&]/[int] result in an lvalue that can be passed by non-const ref while auto x = [int&]/[long] results in an rvalue that cannot. 我不明白auto x = [int&]/[int]导致可以由非const ref传递的左值,而auto x = [int&]/[long]导致的右值不能。

The result of ir/L is long . ir/L的结果是long For arithmetic operator , when binary operators have different types, the result produced will be of the common type; 对于算术运算符 ,当二进制运算符具有不同的类型时,产生的结果将是普通类型; between int and long it would be long . intlong之间会很long

So auto a = ir/L; 所以auto a = ir/L; , the type of a is long . 的类型, along It can't be passed to foo(int&) because you can't bind lvalue reference to non-const with different type. 它不能传递给foo(int&)因为您不能将左值引用绑定到具有不同类型的非const。

On the other hand, given the type of L is int , then for auto a = ir/L; 另一方面,给定L的类型为int ,则对于auto a = ir/L; , the type of a will be int , then everything is fine. 的类型, aint ,那么一切都很好。

About the "the rvalue part of the error", when you pass a long to foo(int&) , firstly the compiler will try to convert it to int , which is a temporary (ie an rvalue) and can't be bound to lvalue reference to non-const. 关于“错误的右值部分”,当您将一个long传递给foo(int&) ,首先编译器将尝试将其转换为int ,这是一个临时(即一个右值),并且不能绑定到左值引用非常量。

long could be implicitly converted to int , and temporary could be bound to lvalue reference to const, so passing a long variable to both bar(int x) and bar(const int&) is fine. long可以隐式转换为int ,而临时变量可以绑定到const的左值引用,因此将long变量传递给bar(int x)bar(const int&)都很好。

BTW: When you write int a = ir/L; 顺便说一句:当你写int a = ir/L; , the result of type long is implicitly converted to int . long类型的结果隐式转换为int So you'll get an int then it's fine to pass it to foo(int&) . 因此,您将获得一个int然后将其传递给foo(int&)很好。

The fact that you've used auto is not relevant. 您使用过auto的事实并不重要。

a is a long type, due to the rules of argument promotion. 由于论据提升的规则, along类型。

Because foo takes the parameter by reference , compilation fails since an int& cannot bind to a long type (even if they are the same size and have the same complement representation). 由于foo 通过引用获取参数,因此编译会失败,因为int&无法绑定到long类型(即使它们的大小相同并且具有相同的补码表示形式)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM