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

时间:2018-02-02 05:06:07

标签: c++ reference const 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"   
}

在考虑它之后这是有道理的,因为在传递值时会创建一个新变量并且可以完成转换,但在传递变量的实际地址时却没有那么多,就像在C ++中一旦变量变成它们的类型真的无法改变。我认为它与这种情况类似:

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

但是如果我使用ref函数取一个const转换工作:

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

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

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

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

2 个答案:

答案 0 :(得分:4)

重点是暂时的。

引用不能直接绑定到不同类型的变量。对于这两种情况,int需要转换为unsigned int,这是一个临时的(从int复制)。临时unsigned int可以绑定到左值引用const(即const unsigned int&),(其生命周期延长到引用的生命周期),但不能绑定到非值的左值引用(即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

答案 1 :(得分:3)

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