1

Given this set of toy structs:

struct foo {
    virtual void print() { cout << "foo";  }
};

struct bar : foo {
    virtual void print() { cout << "bar"; }
};

I would like to create a map which:

  1. Has values which are polymorphic
  2. Has values which are non-const
  3. Is constructed via initalizer_list
  4. Constructs the values within it's initializer_list
  5. Is not initialized using secondary functions/lambdas/macros to convert the initializer_list into a map
  6. Does not require a separate cleanup function

Thus I can't figure out how to make any of these specializations of map work:

  1. map<int, foo*>
  2. map<int, unique_ptr<foo>>
  3. map<int, foo&>
  4. map<int, foo&&>

The only thing that I have found which will work is map<int, shared_ptr<foo>>. I'm unhappy with this because I don't want to allow shared ownership of the values. But it sounds like this is my only option?

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • You can subclass the `std::map` and implement the necessary features. – Mohit Apr 09 '18 at 15:05
  • 2
    @Mohit, no, one should not. – SergeyA Apr 09 '18 at 15:05
  • @SergeyA I'm wandering why one should not? – TioneB Apr 09 '18 at 15:07
  • @Someprogammer The destructor is not virtual amongst other things – Jonathan Mee Apr 09 '18 at 15:09
  • 1
    Related: https://stackoverflow.com/questions/8193102/initializer-list-and-move-semantics I am afraid, `shared_ptr` is your only option. – SergeyA Apr 09 '18 at 15:10
  • 1
    @Someprogammer inheriting from standard container is usually not a good idea. Polymorphic inheritance is out of the question (due to non-virtual destructor) and non-polymorphic inheritance, while possible, usually doesn't worth the trouble. – SergeyA Apr 09 '18 at 15:12
  • @SergeyA Changing to `std::shared_ptr` for this reason sounds not good. I'd prefer using `std::unique_ptr` and `emplace`. – llllllllll Apr 09 '18 at 15:17
  • 1
    @liliscent you can't move-construct the map from initializer list. – SergeyA Apr 09 '18 at 15:18
  • @SergyA T.T I find this greatly disheartening from the language I love. – Jonathan Mee Apr 09 '18 at 15:19
  • That's true, but it's not too much trouble to add an initialization step, comparing to the cost of `std::shared_ptr`. – llllllllll Apr 09 '18 at 15:20
  • @JonathanMee if you look at my link, there is a draft proposal from move-only initializer lists (which I haven't read). You can take it upon yourself to introduce it into C++20. – SergeyA Apr 09 '18 at 15:20
  • @liliscent I dunno. OP is asking about initializer list, listing it as a requirement. I prefer to answer asked questions, rather than invent questions which suite my answer. – SergeyA Apr 09 '18 at 15:21
  • @SergeyA It looks like [the proposal](http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4166.pdf) has been abandoned :( – Jonathan Mee Apr 09 '18 at 15:27
  • @JonathanMee, I guess, the main reason would be `No prototype yet exists. Practice makes perfect.` Proposals are not considered without prototype implementations. – SergeyA Apr 09 '18 at 15:30
  • Thank you the clarification, I'll dig into that – TioneB Apr 09 '18 at 15:38

0 Answers0