Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass std::type_index as template parameter to function template

Tags:

c++

templates

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
like image 535
Gaetan Avatar asked Aug 08 '18 10:08

Gaetan


1 Answers

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.

like image 173
Vittorio Romeo Avatar answered Nov 13 '22 14:11

Vittorio Romeo