为什么持有引用的类可以复制?

时间:2014-04-06 11:50:28

标签: c++ c++11

让一个类持有一个引用我希望下面的代码失败可怜,但它编译:

#include <iostream>

struct ReferenceHolder
{
    std::string& str;

    ReferenceHolder(std::string& str)
    :   str(str)
    {}
};

// Why does this compile?
ReferenceHolder f() {
    std::string str = "Hello";
    return ReferenceHolder(str);
}

int main() {
    ReferenceHolder h  = f();
    std::cout << "Should be garbage: " << h.str << '\n';
    return  0;
}

编译器:g ++ 4.7.2(带-std = c ++ 11)

编辑:即使使用-fno-elide-constructors,它也能很快地编译

2 个答案:

答案 0 :(得分:7)

复制初始化类没有问题,正如您的示例所做的那样:新引用只是初始化为引用与旧引用相同的对象。当然,当函数返回离开引用悬空时,您会得到未定义的行为。

该引用可防止默认初始化和复制分配;因此,以下小改动将因以下原因而失败:

ReferenceHolder h;  // ERROR: can't default-initialise the reference
h = f();            // ERROR: can't reassign the reference.

答案 1 :(得分:1)

此代码具有未定义的行为,请参阅the classic answer from Eric Lippert

h中的引用绑定到f()的返回值中的引用,该引用绑定到返回表达式中的ReferenceHolder,因此h在其范围之外引用str中的f()