0

Is there any way to have a map of different types without casting? I don't mean std::map or boost::map, I mean my own implementation without casting. I don't want to use boost::any or std::any, something like std::variant if it doesn't use casting. I am open to templates or any other fast (no casting) solution.

Would this work:

#define Args double, int, std::vector<double>, std::shared_ptr<double>

class ugly_map_uppearing_nice final
{
public:
    template<typename T>
    void get_ref_risky(const std::string& name, T* t)
    {
        //it = find... it!=end, it->... + get
        // some checks...
        t = &std::get<T>(m_imp[name]);
    };

private:
    std::map<std::string, std::variant<Args>> m_imp;
};
Vero
  • 313
  • 2
  • 9
  • 6
    "fast (no casting) solution" looks like you started your question with delusion that casting is slow. – Slava Apr 27 '22 at 21:33
  • I don't know exactly how casting work, but that's what "THEY" told me! – Vero Apr 27 '22 at 21:34
  • Casting won't be any slower than any other mechanism you (or I) could devise. Can you use polymorphism to wrap your types? (Which you'll still need *some* sort of casting to unwrap your wrapped type.) – Eljay Apr 27 '22 at 21:36
  • 1
    Then probably you should learn how casting works before making "no casting" as a requirement – Slava Apr 27 '22 at 21:37
  • Do you think I can use casting on real time application ticking every millisecond or less? I have to transfer messages of different types (like a system event). Please someone confirms I can. If yes, the I just go with `boost::any`? – Vero Apr 27 '22 at 21:41
  • 2
    `boost::any` / `std::any` will carry a significant performance overhead. It would be better to use `boost::variant` or `std::variant` - read up on it, it's actually very powerful. – Paul Sanders Apr 27 '22 at 21:44
  • Most casts are done at compile time only, so they cannot possibly have impact on runtime. `dynamic_cast` has some runtime checks, but still, it probably won't be noticeable unless done in a tight loop (certainly it shouldn't take a millisecond). `std::any` or `boost::any` are likely to be worse performence-wise, because they need to use type-erasure techniques. – Yksisarvinen Apr 27 '22 at 21:44
  • 2
    A millisecond is an eternity, don't worry about it. Ultimately, the only way to do this "without casts" is to cleverly hide the casts behind a bunch of templates, which won't help performance. – HolyBlackCat Apr 27 '22 at 21:47
  • @Paul Sanders `std::variant` is not generic for a map no? Please see my answer for the response below, this is supposed to be at the developer level, it's up to the user to define the type, my map has to handle it. `std::variant` will definitly need the ***limited** number of types at compile time. Or you talking about something fancier by using `template` and all? – Vero Apr 27 '22 at 21:50
  • @HolyBlackCat how please? I am ready to have ugly code as long as it's fast? (Ah sorry I am editting my response: You are saying it won't help performace) Thanks anyway – Vero Apr 27 '22 at 21:50
  • You asked for "no casting" 4 times in your question, but that is completely incompatible with homogenous use of different types, unless you template the entire code base that would use that "map" or be used by it and instantiate it for each possible type. But that presents another challenge, since it seems you also have a requirement that the "map" be compatible with an unspecified set of types. – François Andrieux Apr 27 '22 at 21:53
  • 2
    C++ is a strongly-typed language. The type of every object must be known at compile time. This is absolute, there are no exceptions to this rule. Your choices are to use either `std::any`, and attempt to guess at the type that's been erased, by `std::any`, or use `std::variant`. There are no other type-safe alternatives. – Sam Varshavchik Apr 27 '22 at 21:54
  • @Vero Your map implementation should be a class template (is it?) Then, many things become possible. – Paul Sanders Apr 27 '22 at 21:58
  • 1
    What do you want to do with this map? Show some use cases. – n. m. could be an AI Apr 27 '22 at 22:07
  • Same example as in one of my previous questions, map will hold details of a request e.g. Request: How many followers does Elon Musk have Map (Response) is just string to int. Other Request could be what was the temperature in the last 10 days Map in this case is Map from String to Vector of Doubles and other requests could have replies that might be new objects :) – Vero Apr 27 '22 at 22:11
  • @Paul Sanders Could you please check my question on top, I added an option, is that what you have in mind. I am null in Parameter pack template thing, tried once and just let go, it's not simple but if you think possible I definitly will give it a shot – Vero Apr 27 '22 at 22:13
  • Kindof. Creating a `std::map` that can hold the type of `std::variant` that you want is what I was driving at, yes, but the rest doesn't look right at all. You're struggling here, I think you need to do some background reading. For a curated list of C++ books, see: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list. There should be something there that will help you improve your skillset. Also, online compilers are a great way to experiment. Personally, I like [Wandbox](https://wandbox.org/), but there are several others. – Paul Sanders Apr 27 '22 at 22:44
  • And please bear in mind that SO is not a tutorial site. It's a Q&A site that is designed to answer tightly focussed, well researched questions and you're not doing that, so there's a limit to what we can do for you here as things stand. When you have a better understanding of what it is you're trying to achieve, and of the tools that C++ has to offer, you should have better luck. – Paul Sanders Apr 27 '22 at 22:47
  • "How many followers does Elon Musk have" doesn't look like C++ code. Show how you want to use your map in a C++ program. – n. m. could be an AI Apr 28 '22 at 21:26
  • The question is clear without any example. How to have a map that holds any type. – Vero Apr 30 '22 at 10:45

0 Answers0