-2

I feel like this should have an answer already but I wasn't able to find it.

I have a vector of shared_ptrs:

vector<shared_ptr<X>> v;

I don't want to do anything with ownership (e.g. copying smart_ptrs) and I just want to go over the elements. Is there any reason why I shouldn't use references (performance or otherwise, e.g. could using references prevent some compiler optimzations or can using references make me run into any trouble)?

for (auto const& x : v)

vs:

for (auto x : v)
NPS
  • 6,003
  • 11
  • 53
  • 90
  • 6
    copying smart pointers is about ownership. You say you dont want to do anything about ownership, so why use anything else than `const auto&` ? – 463035818_is_not_an_ai Aug 07 '23 at 10:39
  • Go from the most restrictive one to the least - Does `const auto&` work for you? Use it. If it does not, then what is wrong? – Quimby Aug 07 '23 at 10:39
  • @463035818_is_not_an_ai That's the gist of my question - using a reference seems like a good optimization but C++ is tricky so maybe I don't know about some important reason against it. – NPS Aug 07 '23 at 10:40
  • the answer is not different to iterating other element types. Use `const auto&` unless you need a copy or modification. – 463035818_is_not_an_ai Aug 07 '23 at 10:40
  • dont write code to implicitly rely on optimizations. Write code the express your intend. You want no copy? Make no copy! – 463035818_is_not_an_ai Aug 07 '23 at 10:41
  • @NPS copy might be important if you want to extend an object lifetime (could be useful for async programming for instance). If it is a single-threaded app and you just want to iterate go with `auto&&` or `const auto&` – Dmitry Aug 07 '23 at 10:42
  • for some reason you think `shared_ptr` would be special regarding `const auto&` or not in the loop, but why do you think so ? Why do you think it would be advanteguous to make a copy? – 463035818_is_not_an_ai Aug 07 '23 at 10:42
  • The way to figure this out is to understand what each approach does, what are the functional differences between them, and then making your decision based on that. This is how to correctly write software: learn what all of that means, instead of asking the Commissar Of Best Practice and blindly follow the Commissar's directives, blindly. – Sam Varshavchik Aug 07 '23 at 10:54
  • @463035818_is_not_an_ai E.g. in functions passing by value is sometimes better because using references prevents optimizations. So I'm wondering if there's anything similar in my case that I don't know about. – NPS Aug 07 '23 at 11:18
  • you write "I don't want to do anything with ownership (e.g. copying smart_ptrs)" with this premise copying the smart pointers is off the table. – 463035818_is_not_an_ai Aug 07 '23 at 11:20
  • you should clarify the question. Currently you are basically asking "When I do not want to copy the smart pointers, should I copy them?" ... the answer can only be No. – 463035818_is_not_an_ai Aug 07 '23 at 11:23
  • @463035818_is_not_an_ai I've edited my question, hopefully now it's better. – NPS Aug 07 '23 at 11:40
  • Unpack the pointer right away `for (auto const& p : v) { auto const& x = *p; /*...*/ }` If the shared_ptr could be nullptr, check for that first and do whatever nullptr handling is appropriate, perhaps `if (!p) continue;`. – Eljay Aug 07 '23 at 11:56
  • 2
    Copying a `shared_ptr` is expensive, because it points at a shared thread-safe reference counter. The copy will (atomically) increment the counter. This atomic operation costs (depending on the architecture) a time equivalent of thousands of arithmetic instructions in local registers. Using references to a `shared_ptr` in the `for`-loop is a perfectly reasonable performance optimization. The `vector>` keeps all `shared_ptr` pointees alive, so there’s no lifespan concern within the loop. But _do_ copy the `shared_ptr` when giving out co-ownership outside the loop’s scope. – Andrej Podzimek Aug 07 '23 at 12:30

1 Answers1

0

Just so this question doesn't stay unanswered I'm answering it myself.

So it looks like there's no reason not to use references (no pitfalls or performance-related issues). Const references, to be specific.

Also please read Andrej Podzimek's comment to my question.

NPS
  • 6,003
  • 11
  • 53
  • 90