I am using a std::shared_ptr
to point to a Node
template<typename T>
class A
{
class Node
{
T data;
std::shared_ptr<Node> link;
Node(T data, std::shared_ptr<Node> link);
};
void push(T data);
std::shared_ptr<Node> top;
};
template<typename T>
A<T>::Node::Node(T data, std::shared_ptr<typename A<T>::Node> link) :
data(data), link(link)
{
}
template<typename T>
void A<T>::push(T item)
{
if (top == nullptr)
{
top = std::make_shared<typename A<T>::Node>(new typename
A<T>::Node(item, nullptr));
}
else
{
top = std::make_shared<typename A<T>::Node>(new typename A<T>::Node(item, top));
}
}
The resulting declarations and definitions results in the compiler error
Severity Code Description Project File Line Suppression State Error C2664 'Stack::Node::Node(const Stack::Node &)': cannot convert argument 1 from 'Stack::Node *' to 'const Stack::Node &' memory 901
What do I need to change to conform to <memory>
?
A constructor of std::shared_ptr<T>
accepts a pointer to T
which you have created with new
.
The function std::make_shared<T>(args...)
does the new
for you instead. The arguments you pass to make_shared
will be passed on to the constructor of T
. So you should almost never pass it a pointer created by new
(unless you really want to new
a T
, and then pass that pointer as an argument to create another T
!).
So for example, instead of:
std::make_shared<typename A<T>::Node>(
new typename A<T>::Node(item, top))
do just:
std::make_shared<typename A<T>::Node>(item, top)
(By the way, you don't actually need most of those typename A<T>::
qualifiers. Just plain Node
is in scope whenever you're in the scope of A<T>
or A<T>::Node
, both in the class definitions and member definitions of that class after the member name. A<T>::Node
without the typename
would also work in those contexts because of the "member of the current instantiation" rule.)