Reputation: 1073
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
Reputation: 2695
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