3

I've wrote a shared_ptr the class definition is as below:

template <typename T>
class shared_ptr {
private:
...
public:
  shared_ptr(T* p);
  shared_ptr(shared_ptr& src);
  shared_ptr& operator=(shared_ptr const& src);
};
shared_ptr<T> make_shared(Args&&... args) {
  return shared_ptr<T>(new T(std::forward<Args>(args)...));
}
// the function call:
shared_ptr<int> a = make_shared<int>(1);

it won't work and the compiler error me that

non-const lvalue reference to type shared_ptr<> cannot bind to rvalue of type shared_ptr<>

I add a rvalue copy constructor:

template <typename T>
shared_ptr(shared_ptr&& src) {
  print("rvalue");
}

But no statement are printed out.

my environment is visual studio 2019 with MSVC++.

if my rvalue copy constructor is not executed, why it errors when there is no rvalue copy constructor? (I guess it's a RVO but seems it's not)

thank you all for the answer and comment , I will learn to answer good question next time.

Pan
  • 125
  • 2
  • 5
  • @Enlico It's long indeed, but don't we encourage users to debug their code? – user202729 Sep 03 '21 at 12:46
  • Might be a duplicate of [c++ - Why is a public copy constructor required even if it is not invoked? - Stack Overflow](https://stackoverflow.com/questions/20455382/why-is-a-public-copy-constructor-required-even-if-it-is-not-invoked) regarding the RVO part, but I'm not sure if the copy/move is a significant different. – user202729 Sep 03 '21 at 12:51
  • @user202729, we should also encourage to "debug" the prose. – Enlico Sep 03 '21 at 12:52
  • I am so sorry, i am new to here, I should noticed that my code contain too many invalid information and waste your time, I have fix that and I will learn to how to ask good question, I am so sorry indeed, thank you all. – Pan Sep 03 '21 at 12:54
  • 2
    @JunzhongPan - Don't apologize. While its true that your post could have been more focused, the way it was brought up is inexcusable. – StoryTeller - Unslander Monica Sep 03 '21 at 12:59
  • 1
    @DaveNewton, I'll be softer next time. – Enlico Sep 03 '21 at 13:08
  • `I add a rvalue copy constructor` That's called a move constructor. – eerorika Sep 03 '21 at 13:32

1 Answers1

3

The issue is that your copy constructor accepts a non-const lvalue reference for some reason, which can't bind to an rvalue. Just make it const:

shared_ptr(shared_ptr const& src) noexcept;

and the move constructor won't be required. However it's a good idea to implement the move constructor/assignment anyway, to not pointlessly jerk the reference counter.

yuri kilochek
  • 12,709
  • 2
  • 32
  • 59