与将非常量左值绑定到构造函数中的右值有关的错误

时间:2019-07-06 06:57:09

标签: c++ templates shared-ptr rvalue

对于我的头文件中的以下模板定义,

template<typename T>
    class node{
        private:
            T& data;
            shared_ptr<node<T>>& next;

        public:
            node(T&);
            ~node();
    };

template<typename X>
  class list{
        private:
            shared_ptr<X>& head;
        public:
            list();
            ~list();
     };

main()中的以下代码行:

list<node<string>>menu;

对于构造函数内部shared_ptr<X>& head的成员初始化,我收到以下编译错误:

template<typename X>
list<X>::list():head(make_shared<X>(NULL)){
}

error: cannot bind non-const lvalue reference of type "std::shared_ptr<node<std::basic_string<char> > >" to an rvalue of type "std::shared_ptr<node<std::basic_string<char> > >"
 list<X>::list():head(make_shared<X>(NULL)){
                                          ^

我的理解是,错误源于试图将通过调用make_shared()生成的右值绑定到左值shared_ptr<X>& head

如何解决此错误?

1 个答案:

答案 0 :(得分:2)

问题如下,您正在创建临时

make_shared<X>(NULL)

,它将在执行该行后死亡,并且类中的引用将悬空(即引用已被破坏的对象),如果尝试访问该引用,您将处在未定义的行为范围内(您的程序可能会崩溃,或者更糟的是继续处于损坏状态)。 解决此问题的一种方法是,在所有类中不使用对shared_ptr的引用,而直接使用shared_ptr,这样更安全。

第二,您可能要使用nullptr而不是NULL

最后,我认为您误解了引用应做的事情:它们与资源所有权无关,而只是允许访问资源,当您引用某项内容时,必须确保其他人是只要您想通过引用访问该资源,就可以保持该资源的生存期(有一个例外:通过本地const ref延长生存期,请参见https://blog.galowicz.de/2016/03/23/const_reference_to_temporary_object/)。