0

I have a function which returns a shared pointer of type const A.

std::shared_ptr< const A> getPointer() const;

and I have a function which needs a shared_ptr of type A.

void foo(std::shared_ptr<A> a);

When I try to call my function I get the following message:

error: no viable conversion from 'shared_ptr< const A>' to 'shared_ptr< A >'

I do not care about performance. This line of code is in a GUI and by all means not part of any hot code. (This means I do not care if I create a copy of A or not)

What is the easiest solution to fix this?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
user7431005
  • 3,899
  • 4
  • 22
  • 49
  • 10
    There's no safe way to cast the pointer. This is the same as trying to convert `const A*` to `A*`. The pointer you got from `getPointer()` is not meant to be used by anything that could modify the pointed object. And you mention the solution in the question. If you don't care about the cost of copying the `A`, then copy the `A` and pass that. – François Andrieux Nov 12 '18 at 15:20
  • 1
    Does the operation in `foo` modify the object? Can you change the declaration of `foo`? Can you change the prototype of `getPointer`? – Fantastic Mr Fox Nov 12 '18 at 15:24
  • I cannot change anything about `foo` – user7431005 Nov 12 '18 at 15:25
  • @user7431005 And `getPointer`? – Fantastic Mr Fox Nov 12 '18 at 15:26
  • 1
    ok, I now create a working solution using `foo(std::make_shared< A >(*getPointer())` I guess this will copy the data? – user7431005 Nov 12 '18 at 15:32
  • 4
    TBH making a copy might not work as `foo()` clearly wants shared ownership over the data. It may need access to the *exact same data* stored behind the `getPointer()` call. So we really need more information. – Galik Nov 12 '18 at 15:35
  • @user7431005 yes. You should answer your own question. Answer like you wern't the one asking. Hello double personality. – YSC Nov 12 '18 at 15:35
  • Sometimes you just need somebody to fix your head ;-) Maybe I should go home now – user7431005 Nov 12 '18 at 15:37
  • 1
    @Galik makes a good point. If `foo` didn't care to share ownership it wouldn't require a `std::shared_ptr` in the first place. In addition, since `foo` expects a non-`const` `A` you have to assume it intends to modify the `A` in some way, and passing a copy will lead to `foo` not accomplishing what it's intended to do. – François Andrieux Nov 12 '18 at 15:38
  • 1
    There are two potential pitfalls with copying the value: one, as @Galik mentions, shared pointer hints there might be a need for truly shared object (otherwise, functions would use unique or non-owning pointer!). Second, there could be inheritance and slicing issues. As for the casting, if original pointer was not created const, it could be safely const-casted away. – SergeyA Nov 12 '18 at 15:42
  • @FrançoisAndrieux Answer in the answer section please and thank you – Lightness Races in Orbit Nov 12 '18 at 15:46
  • 3
    Although there are circumstances when a `const_cast` would work and there are circumstances when making a copy would work, there ***should*** be a better way. Both those fixes, even if they happen to work in this case, are *brittle* and easily broken. - either way brings the design into question. You probably need to rethink how all these pieces fit together. Is someone being over-liberal with shared_ptrs? Unless you can provide more context - a working example? I don't think anyone can give you a good answer, just some dodgy fixemups. – Galik Nov 12 '18 at 15:50

1 Answers1

2

https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

foo(std::const_pointer_cast<A>(getPointer()));

If your function will alter the pointer and you do not wish for this to happen:

auto ptr = std::make_shared<A>(*(getPointer().get()));
foo(ptr);

Disclaimer:

The first option presents the risk if foo modifies the received pointer.

The second option makes a copy of the entire object and requires a copy constructor.

Victor Padureanu
  • 604
  • 1
  • 7
  • 12