I am trying to write a generic function, using template, that is able to return bool, integer or char* or string.
template<typename entryType>
entryType getEntry(xml_node node, const char* entryKey)
{
...
if (is_same<entryType, bool>::value) {
return boolvalue; //returning a boolean
}
else if(is_same<entryType, int>::value) {
return a; //this is an integer
}
else if (is_same<entryType, char*>::value) {
return result; //this is a char*
}
}
and I would like to be able to call it like:
bool bPublisher = getEntry<bool>(node, "Publisher");
int QoS = getEntry<int>(node, "QualityOfService");
char* sBrokerUrl = getEntry<char*>(node, "BrokerUrl");
as an alternative for the char*, a string would be also fine:
string sBrokerUrl = getEntry<string>(node, "BrokerUrl");
I get errors like: "cannot convert from 'bool' to 'char*'. I understand the problem, the compiler is not able to detect that the code execution branch depends on the type I give. I just can't find a solution for that. Could anyone help me? Thanks.
Since C++17 you can use constexpr if; whose condition part will be evaluated at the compile time, and if the result is true then the statement-false part (otherwise the statement-true part) will be discarded. (Thus won't cause the error.) e.g.
if constexpr (is_same<entryType, bool>::value) {
return boolvalue; //returning a boolean
}
else if constexpr (is_same<entryType, int>::value) {
return a; //this is an integer
}
else if constexpr (is_same<entryType, char*>::value) {
return result; //this is a char*
}
LIVE
For older versions of C++, you can solve this by forwarding to one of the overloaded functions that return result through argument passed by reference:
template<typename entryType>
entryType getEntry(xml_node node, const char* entryKey)
{
entryType result = entryType();
this->getEntry(node, entryKey, result);
return result;
}
void getEntry(xml_node node, const char* entryKey, bool& result);
void getEntry(xml_node node, const char* entryKey, int& result);
void getEntry(xml_node node, const char* entryKey, char const *& result);
Or you can use std::enable_if (since C++11):
template<typename entryType>
typename std::enable_if<std::is_same<entryType, bool>::value, entryType>::type
getEntry(xml_node node, const char* entryKey) {
...
}
But first solution, IMO, is more readable. You can make overloaded functions private, if you don't want to expose them.
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