const初始化的const引用

时间:2016-06-25 10:30:04

标签: c++

假设我有A级:

class A {
    int i;
public:
    A(){};
    A(int i){this->i=i;};
};

一个简单的测试功能:

void test(const A &a){...}

现在,如果我这样做:

int main()
{
    test(2);
} 

它编译并调用A(int i)构造函数。但是当我将参数更改为非const时:void test(A &a)我收到编译错误 这些情况之间有什么区别,为什么第一个允许,第二个不允许,以及在第一个案例的初始化中实际发生了什么?

3 个答案:

答案 0 :(得分:1)

这两种情况的区别在于允许C ++编译器创建临时对象以传递给接受const引用的函数,但是接受非const引用的函数必须与实际对象一起提供

当你致电test(2)实际发生的事情是这样的:

A hidden(2);
test(hidden);

编译器创建hidden对象,使用2对其进行初始化,并将结果传递给test。由于test保证不会修改A,因此这很好。

test无法提供此类保证时:设想设置新值的test

void test(A& a) {
    a.i++; // let's pretend "i" is public
}

如果您使用实际对象(test)致电A a(3); test(a);,则可以在a返回后从test收集更新结果。另一方面,调用test(2)无法访问更新结果。这表示逻辑中存在潜在错误,因此编译器将其视为错误。

答案 1 :(得分:0)

  

在第一种情况的初始化中实际发生了什么?

在第一种情况下,临时A将由A::A(int)隐式构造,然后绑定到对const的左值引用。 test(2);的效果与test(A(2));相同。

临时不能绑定到非const的左值引用,这就是第二种情况失败的原因。

答案 2 :(得分:0)

这是一个有趣的案例。使用const,您可以绑定对rvalue的引用。下面是一个更简单的例子。

int get_num()
{
    return 2;
}

int main(){
    int& p = get_num(); // This is a compiler error. Can't create a non-const reference to an rvalue
    const int& q = get_num(); // this will work. Can create const reference to an rvalue
}

这是c ++标准的一部分。