0

I am trying to return a unique_ptr from a vector of base class pointers to apply polymorphism as unique_ptr can not be copied. Is there any way around this? See he function.

#include <bits/stdc++.h>

using namespace std;

class shape {
public:
  virtual void foo() = 0;
};

class circle : public shape {
public:
  virtual void foo() override {cout << "I am circle" << endl;}
};

class square : public shape {
public:
  virtual void foo() override {cout << "I am square" << endl;}
};

unique_ptr<shape> da(int x) {
  if(x)
    return make_unique<circle>();
  return make_unique<square>();
}

unique_ptr<shape> he(const vector<unique_ptr<shape>> &t, int x) {
  return t[x];
}
  • 2
    If you want to copy a smart pointer then `unique_ptr` might not be the correct solution. – john Sep 12 '22 at 21:24
  • then the only way is to use raw pointers, right? – Mohamed Atef Sep 12 '22 at 21:28
  • 1
    Side note: The combination of `#include ` and `using namespace std;` often turns out to be an unforced error. You should avoid both of them individually ([why](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) and [why](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)) but when you combine them... Zoinks. – user4581301 Sep 12 '22 at 21:29
  • @user4581301 the real program is very large. this is just a source I use for competitive programming – Mohamed Atef Sep 12 '22 at 21:30
  • No worries. Just be really really careful and make sure you have precompiled headers set up correctly otherwise you'll find `#include ` starts costing you time. – user4581301 Sep 12 '22 at 21:32
  • 1
    @user4581301 thanks a lot the links are very informative – Mohamed Atef Sep 12 '22 at 21:33
  • Does the receiver have any ownership stake in the pointed-at object? Can it possibly outlive the object inside the `vector` referred to by `t`? If both are no, you're right. Raw pointer. Otherwise consider `shared_ptr`. – user4581301 Sep 12 '22 at 21:34
  • ***then the only way is to use raw pointers, right*** No that is incorrect. There are other ways depending on your needs. – drescherjm Sep 12 '22 at 21:38
  • Whichever C++ textbook taught you to use `` -- you need to throw it away and get a different C++ textbook. If you copied that off some web site, without any explanation, don't visit that web site any more. If you saw this in some clown's Youtube video, unsubscribe from that channel, you're not learning proper C++. Most C++ compilers in the world don't have this header file, and will not compile the shown code. – Sam Varshavchik Sep 12 '22 at 21:39
  • With reference to function `he`, what are the ownership semantics for the `unique_ptr` you pass in? If you can clarify that in your own mind you should be able to decide how best to modify the signature of that function such that it (a) compiles, and (b) does the right thing. Or if you can't decide how to do that, then add a description of said ownership semantics to your question (you might want to guarantee that the underlying pointer remains alive until the caller is done with it, for example) and you should then get better targeted responses. – Paul Sanders Sep 12 '22 at 22:24

1 Answers1

2

You cannot copy a unique_ptr. Here's a couple of options

Return a regular pointer

shape* he(const vector<unique_ptr<shape>> &t, int x) {
  return t[x].get();
}

Return a reference to the unique_ptr

const unique_ptr<shape>& he(const vector<unique_ptr<shape>> &t, int x) {
  return t[x];
}

Hard to say which is right (if any), but they should both compile.

john
  • 85,011
  • 4
  • 57
  • 81