0

This won't work:

struct MyData {
    MyData();
    std::string foo;
    long bar;
}

class MyTest {
public:
    std::unordered_set<MyData&> data;
}

I want to be as efficient as possible and don't want the objects to be copied when accessed or inserted.

Why does std::unordered_set<MyData*> data; work, if the pointer is just the address and so is the reference?

Simon Pio.
  • 115
  • 1
  • 14
  • You can't use reference types as value with _any c++ standard container class_ (directly). – πάντα ῥεῖ Oct 27 '20 at 21:13
  • 1
    It's a bit clunky IMO, but you can use [`std::reference_wrapper`](https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper) for this. – 0x5453 Oct 27 '20 at 21:14
  • @0x5453 2nd answer in the dupe. – πάντα ῥεῖ Oct 27 '20 at 21:15
  • Or just use pointers or const pointers (not pointers to const.) – Anonymous1847 Oct 27 '20 at 21:16
  • If you want it to be efficient, make a nondefault constructor and do data.insert(Mydata(foo,bar)); then it only exists in data – mkamerath Oct 27 '20 at 21:17
  • What is a reference type anyway? If a reference is nothing but another name for an existing object, not an object itself, can you even say you there's such a thing as a reference type? – user4581301 Oct 27 '20 at 21:18
  • @mkamerath where is the difference if I use `std::unordered_map ...` and first initialize and then insert? `MyData d(foo, bar); data.insert(d);` – Simon Pio. Oct 27 '20 at 21:22
  • @user4581301 I am also curious why I can use pointers but not references... – Simon Pio. Oct 27 '20 at 21:23
  • @Simon Pio, if you do it the way I said, the only way to access the data is in the unordered_map. If you do it the way you said, you’ll have the object d that will exist outside of data. Inside of data will be a copy of d from when it was inserted – mkamerath Oct 27 '20 at 21:28
  • @SimonPio. That one I can answer. 1. A container holds objects and references aren't objects. With a reference there may literally be nothing to store. 2. Containers do a lot of copying, moving and assigning but references cannot be assigned. You assign to a reference and you change the referred-to object, not what the reference references. – user4581301 Oct 27 '20 at 21:28
  • @user4581301 So a pointer is also seen as object? I just don't get why I can pass the address of the object but not the reference which is the address of the object. EDIT: A pointer can be reassigned... got it – Simon Pio. Oct 27 '20 at 21:35
  • 1
    @SimonPio. References simply are not objects. They do not have a size, they do not have their own address, they cannot be part of an array. This makes it very difficult to hold them in a container. If you want to store a reference you can use `std::reference_wrapper` which is bit like a reference but it is also an object. – François Andrieux Oct 27 '20 at 21:41
  • A pointer is an object that contains an address. [Here's what I mean when I'm saying object](https://en.cppreference.com/w/cpp/language/object). I'm not meaning an instance of a class. A pointer has all the requirements (well, most of them. Things get a bit fuzzy with class members and `this` is a real weirdo). – user4581301 Oct 27 '20 at 21:42
  • [More details on François Andrieux's comment above](https://en.cppreference.com/w/cpp/language/reference). Of particular interest is *References are not objects; they do not necessarily occupy storage, although the compiler may allocate storage if it is necessary to implement the desired semantics (e.g. a non-static data member of reference type usually increases the size of the class by the amount necessary to store a memory address). Because references are not objects, there are no arrays of references, no pointers to references, and no references to references:* – user4581301 Oct 27 '20 at 21:47
  • *"...if the pointer is just the address..."* Correct. *"...and so is the reference"* Incorrect. – Eljay Oct 27 '20 at 23:19

0 Answers0