Vinod
Vinod

Reputation: 1073

error related to binding non-const lvalue to rvalue in constructor

For the following template definitions in my header file,

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();
     };

and the following line of code in main():

list<node<string>>menu;

I get the following compilation error for the member initialization of shared_ptr<X>& head inside the constructor:

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)){
                                          ^

My understanding is that the error stems from trying to bind the rvalue generated by call to make_shared() to lvalue shared_ptr<X>& head.

How can I resolve this error?

Upvotes: 0

Views: 666

Answers (1)

The problem is the following, you are creating a temporary

make_shared<X>(NULL)

that will die after the line is executed, and the reference in your class will be dangling (i.e. referencing something that has been destroyed), if you try to access the reference you will be in undefined behavior territory (your program can crash, or worse continue in a corrupted state). A way to fix it would be to not use references to shared_ptr but directly shared_ptr in all your classes which is way safer.

Secondly, you might want to use nullptr instead of NULL

Lastly, I think you are misunderstanding what the references are supposed to do: they are not about ownership of a resource, but simply allow access to a resource, when you have a reference to something you must be sure that somebody else is keeping that resource alive for as long as you want to access the resource via the reference (there is an exception: lifetime extension via a local const ref, see https://blog.galowicz.de/2016/03/23/const_reference_to_temporary_object/).

Upvotes: 3

Related Questions