1

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>?

Mushy
  • 2,535
  • 10
  • 33
  • 54
  • Please post the full error message, not just the first line. – Ken Y-N Oct 06 '17 at 00:36
  • And a more complete example that actually doesn't compile. What you have here compiles fine in VS 2017. – Retired Ninja Oct 06 '17 at 00:36
  • `std::make_shared` takes as an argument a reference to an object, but you are using `new` to make a pointer, thus, probably, your `cannot convert argument 1 from 'Stack::Node *' to 'const Stack::Node &'` error. – Ken Y-N Oct 06 '17 at 00:40
  • You mean ``, not `memory.h`. – aschepler Oct 06 '17 at 00:47
  • @KenY-N The only other information on this error I have is [here](https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(C2664)&rd=true) – Mushy Oct 06 '17 at 01:47
  • @aschepler Thank you and corrected – Mushy Oct 06 '17 at 01:48
  • @RetiredNinja I am using Visual Studio 2015 and `` is not compiling correctly. Did you set up VS2017 to not ignore warnings and instead treat them as errors? – Mushy Oct 06 '17 at 01:50
  • I have no warnings in *just the code you posted*. If I fix the issues where you didn't make the constructor public in Node, or the Node definition and push function public in A, and I add headers and make a main I can duplicate your error. My point was, your example is not complete, and the error you posted was not generated from the posted code. (Stack != A) The error is also not complete since you posted 1 out of the 25 lines it generates. – Retired Ninja Oct 06 '17 at 02:01
  • @RetiredNinja That is the point though. You have to build a real example and then the warning which becomes an error is plainly visible. As I pointed out, that is all the compilation error info I have as presented to me by Visual Studio 2015 with a link directly to Microsoft's page describing it in more detail. That written, what I posted above does generate the error and an answer has been posted correcting that error; namely don't use `new` with `std::make_shared` and it works, tested and all. Answer accepted. – Mushy Oct 06 '17 at 02:30
  • It's your job when you ask a question to make a complete example, not ours. – Retired Ninja Oct 06 '17 at 02:57

1 Answers1

5

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.)

aschepler
  • 70,891
  • 9
  • 107
  • 161