Is there any way to use template as type in a map in C ++ 17?
template<typename T>
std::map<std::string, T/* tipo desconhecido, pode ser qualquer tipo */> map_exemplo;
Is there any way to use template as type in a map in C ++ 17?
template<typename T>
std::map<std::string, T/* tipo desconhecido, pode ser qualquer tipo */> map_exemplo;
c ++ 17 introduced the type std::any
, a container capable of saving objects of any kind *. Examples:
#include <any>
#include <string>
int main() {
std::any a = 42; // int
a = 3.14f; // float
a = true; // bool
a = std::string("Hello, World!"); // std::string
}
You can redeem the value of a std::any
to its original type with std::any_cast
.
In your problem, the element value type of map_exemplo
could be set to std::any
, so every time you create a new entry in map_exemplo
, the element type will not matter. Like everything is not a sea of roses, however, to iterate over the elements of this container, you will have to code the types you expect the elements to have:
#include <map>
#include <any>
#include <string>
int main() {
std::map<std::string, std::any> map_exemplo;
map_exemplo["a"] = 42;
map_exemplo["b"] = 3.14f;
map_exemplo["c"] = true;
for (const auto &[chave, valor] : map_exemplo) {
if (auto ptr = std::any_cast<int*>(&valor)) {
// ...
}
else if // ...
}
}
The purpose of std::any
is more intended to replace the use of type void *
to save user data. In your case, the type std::variant
would suit your needs better, because with it you can define which types are expected, and access to objects is done with std::visit
:
#include <map>
#include <variant>
#include <string>
#include <cstdio>
// Classe ajudante para sobrecarregar lambdas.
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
int main() {
std::map<std::string, std::variant<int, float, bool>> map_exemplo;
map_exemplo["a"] = 42;
map_exemplo["b"] = 3.14f;
map_exemplo["c"] = true;
for (const auto &[chave, valor] : map_exemplo) {
std::visit(overloaded {
[] (int i) { std::printf("int: %d\n", i); },
[] (float f) { std::printf("float: %f\n", f); },
[] (bool b) { std::printf("bool: %s\n", b ? "true" : "false"); }
}, valor);
}
}
* Some rules apply here so that an object can be saved by a std::any
, such as satisfying the requirement to be constructive.