Why does const allow implicit conversion of references in arguments?

送分小仙女□ 提交于 2020-02-24 09:24:10

问题


This may sound like a silly question, but I was confused about this following behaviour:

void funcTakingRef(unsigned int& arg) { std::cout << arg; }
void funcTakingByValue(unsigned int arg) { std::cout << arg; }

int main()
{
    int a = 7;
    funcTakingByValue(a); // Works
    funcTakingRef(a); // A reference of type "unsigned int &" (not const-qualified)
                      // cannot be initialized with a value of type "int"   
}

After thinking about it this kind of makes sense because in passing by value a new variable is created and conversion can be done, but not so much when passing the actual address of a variable, as in C++ once variables are made their type can't really change. I thought it's similar to this case:

int a;
unsigned int* ptr = &a; // A value of type int* cannot be used to 
                        // initialise an entity of type "unsigned int*"

But if I make ref function take a const the conversion works:

void funcTakingRef(const unsigned int& arg) { std::cout << arg; } // I can pass an int to this.

However not the same in the case of pointer:

const unsigned int* ptr = &a; // Doesn't work

I'm wondering what the reason for this is. I thought my reasoning was right that implicit conversion when passing by value made sense as a new variable is made, whereas because in C++ types never change once created you can't get an implicit conversion on a reference. But this doesn't seem to apply in a const reference parameter.


回答1:


The point is the temporary.

References can't bind to variables with different type directly. For both cases int needs to be converted to unsigned int, which is a temporary (copied from int). The temporary unsigned int could be bound to lvalue-reference to const (i.e. const unsigned int&), (and its lifetime is extended to the lifetime of the reference,) but can't be bound to lvalue-reference to non-const (i.e. unsigned int&). e.g.

int a = 7;
const unsigned int& r1 = a; // fine; r1 binds to the temporary unsigned int created
// unsigned int& r2 = a;    // not allowed, r2 can't bind to the temporary
// r2 = 10;                 // trying to modify the temporary which has nothing to do with a; doesn't make sense



回答2:


const & allows the compiler to generate a temporary variable, which gets thrown away after the call (and the function can’t change it, as it is const).
For non-const, the function would be able to modify it, and the compiler would have to transfer it back to the type it came from, which would lead to all kinds of issues, so it’s not allowed/possible.



来源:https://stackoverflow.com/questions/48576011/why-does-const-allow-implicit-conversion-of-references-in-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!