Consider the following code (which works fine):
namespace fruit {
struct apple{};
}
namespace language{
struct english{};
}
typedef std::pair<std::string, std::type_index> myPairType;
std::unordered_map<std::string, myPairType> myMap =
{
{"paul", {"likes", std::type_index(typeid(fruit::apple))} },
{"jonas", {"likes", std::type_index(typeid(language::english))} }
};
Now I have the following function template:
template <typename T>
void GenerateProfile(void* data) {
T* data_casted = reinterpret_cast<T*>(data);
//the data are then set to some database
}
How can I pass fruit::apple
or language::english
as template parameter when calling my GenerateProfile function?
myPairType myPair = myMap.at("paul"); //This works fine
fruit::apple* ptr = nullptr; //or fruit::apple* ptr = ...
GenerateProfile<?>(ptr);
//GenerateProfile<myPair.second>(ptr) is not compiling
//GenerateProfile<fruit::apple>(ptr) this one compile but I want to acess fruit::apple from myPair
std::type_index
stores type information at run-time. Templates are a compile-time construct. Therefore you need a way of converting from the run-time world to the compile-time one: a chain of if
/else
statements works.
if(myPair.second == std::type_index(typeid(fruit::apple)))
{
GenerateProfile<fruit::apple>(...);
}
else if(myPair.second == std::type_index(typeid(language::english)))
{
GenerateProfile<language::english>(...);
}
This can obviously be generated for you using template metaprogramming.
However, your approach is a code smell - do you actually need the type information at run-time? You might want to reconsider your design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With