为什么const允许参数中引用的隐式转换?

Zeb*_*ish 2 c++ const reference implicit-conversion

这听起来像是一个愚蠢的问题,但是我对以下行为感到困惑:

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"   
}
Run Code Online (Sandbox Code Playgroud)

经过仔细考虑,这是有道理的,因为在传递值时会创建一个新变量并可以进行转换,但是在传递变量的实际地址时并不需要那么多,就像在C ++中,一旦使变量的类型不能真的改变了。我认为这类似于这种情况:

int a;
unsigned int* ptr = &a; // A value of type int* cannot be used to 
                        // initialise an entity of type "unsigned int*"
Run Code Online (Sandbox Code Playgroud)

但是,如果我使ref函数采用const,则转换有效:

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

但是在指针的情况下是不一样的:

const unsigned int* ptr = &a; // Doesn't work
Run Code Online (Sandbox Code Playgroud)

我想知道这是什么原因。我以为我的推论是正确的,因为当通过值传递时进行隐式转换作为新变量是有意义的,而在C ++中,类型一旦创建就永远不会改变,就无法在引用上进行隐式转换。但这似乎不适用于const引用参数。

Aga*_*nju 5

const &允许编译器生成一个临时变量,该变量在调用后被丢弃(并且函数无法更改它,因为它是const)。
对于非常量,函数将能够修改它,编译器将不得不将其传输回它来自的类型,这将导致各种问题,因此不允许/不可能。


son*_*yao 5

关键是暂时的。

引用不能直接绑定到具有不同类型的变量。对于这两种情况,都int需要将转换为unsigned int,这是临时的(从复制int)。临时对象unsigned int可以绑定到constconst unsigned int&)的左值引用,(并且其生存期延长到引用的生存期,),但不能绑定到非常量的左值引用(即unsigned int&)。例如

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
Run Code Online (Sandbox Code Playgroud)