2

Is there any way in C++ to create runtime-modificable collection that matches integer to template type?

First I though about:

std::map<uint32_t, std::type_index> type;

but std::type_index has very small usefulness. I need to be able to cast by that type and use it as argument for std::is_convertible

So the api should be able to something like that:

my_collection.add<1234, std::string>();
my_collection.get<1234>()::type // type is std::string

Or actually anything else close enough I can use in runtime :)

PiotrK
  • 4,210
  • 6
  • 45
  • 65
  • Templates are compile-time constructs. This could be possible if the collection is also a compile-time thing, but you can't make compile-time things at run-time. – super Jun 25 '18 at 18:59
  • 1
    Not really. Types must be known at compile time. One thing you could use is `std::variant`/`std::any` and `std::visit`. – NathanOliver Jun 25 '18 at 18:59
  • @NathanOliver I cannot use `std::variant,` I tried already with `boost::spirit::has_any` , but it does not have `visit` code for that in spirit framework – PiotrK Jun 25 '18 at 19:11
  • 1
    @PiotrK, if performance doesn't matter, one can conjure a monstrosity from `std::vector` and some tag types. – Incomputable Jun 25 '18 at 19:43
  • @Incomputable I am actually trying something like this, but I am at C++14 and I don't have `std::any`, only `boost::any` and it does not includes visitor pattern I believe... – PiotrK Jun 25 '18 at 19:47
  • 1
    @PiotrK, I'll use `std::any` in my answer then. After I'll implement and try it out. – Incomputable Jun 25 '18 at 19:48
  • 1
    Some sort of tuple? – user7860670 Jun 25 '18 at 19:51
  • @PiotrK, I forgot that the mapping is the other way around. Let me rewrite it a little bit more. – Incomputable Jun 25 '18 at 20:04
  • @Incomputable Okay, thanks! :) – PiotrK Jun 25 '18 at 20:05
  • @PiotrK, unfortunately it seems like Oliver is right. The only thing one can do is to return something that is at least checkable. E.g. if one keeps testing, they'll find the type. Perhaps a dynamically typed language will suit this problem more? I believe interface change might reveal a solution, but runtime type manipulation in C++ is not a good idea. – Incomputable Jun 25 '18 at 20:09

1 Answers1

2

No.

If your list of types you support can be finitely and centrally enumerated, std::variant or boost::variant or a roll-your-own can be used.

If your list of operations on the type you support can be finitely and centrally enumerated, std::any or boost::any together with type erasure techniques can be used to solve your problem. Here is an overly generic system to type erase nearly any single-dispatch operation.

You can use std::any or boots::any to have a non-centrally yet locally finitely enumerated list of types, but only the exact types known at each enumeration location are in play at that location.

You can do a combination of the above.

Failing that, you are entering the world of runtime compiling of dynamic C++ libraries and passing the result, and/orraw C++ with source code, around. Doing on the fly compiling.

All of this will depend on what your exact, actual problem is for which that you came up with this as a "solution"; there is probably going to be a related question for which your answer is "yes", and that related question is probably what you actually need to solve.

But the answer to your question as posed is simply "No".

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • How can I use `boost::any` for "non-centerally yet locally finitely enumerationed'? – PiotrK Jun 25 '18 at 20:26
  • I found this answer: https://stackoverflow.com/a/13399138/151150 and it actually satisfy my problem :) – PiotrK Jun 25 '18 at 20:29