Suppose I have something like this:
template <typename T, typename ...args>
static std::map<T, std::tuple<args...>> MyMaps;
Every type is known on compile time. So for every configuration of types added to the map, a new map is created.
Is there a way to search in all instances of map that matches the T parameter with just the key (and the key type)?
CodePudding user response:
Depends on what you mean by search. You can collect them into a container and then do any kind of processing you like:
#include <any>
#include <iostream>
#include <map>
#include <typeindex>
#include <vector>
std::map<std::type_index, // key type
std::vector<std::any> // pointers to the maps with this key type
>
key_to_map;
template <typename T, typename... args>
auto& MyMap() {
static std::map<T, std::tuple<args...>> map = [] {
key_to_map[std::type_index(typeid(T))].push_back(&map);
return decltype(map){};
}();
return map;
}
int main() {
MyMap<int, char, double>();
MyMap<char, int, double>();
MyMap<int, short, long>();
std::cout << "Number of maps with `int` as the key is "
<< key_to_map[std::type_index(typeid(int))].size() << '\n';
}
CodePudding user response:
No.
The underlying problem one would have to solve is determining whether a template variable has been instantiated or not. Otherwise have fun searching through infinitely many possible instantiations.
C provides no tools for answering such questions because implementation would be near impossible. Mainly due to separated compilation and linking processes. TL;DR; would be that a translation unit(TU) does not contain enough information yet and the linker is too late as the code has already been generated.
Each translation unit is compiled separately into an object file. Each TU saw (hopefully the same) template definition from which it instantiated all variables used in this TU. But it does not and cannot know about any instantiated variables in other TUs.
Job of the linker is to collect all those object files, resolve the exported and missing symbols, including de-duplication of inline
definitions, and finally to create the executable/library.
Only just before the final step, the question could be answered. But at this point, the code has already been generated and cannot be changed. And even if it could involve the compiler to create new code again, what if the new code generates even more instantiations, should the linker try again? That borders on runtime-reflection.