I'm trying to create a generic function toStr() for several enum classes but I'm having some issues.
I have these enum classes and maps to convert the value of the enums to string.
'''
enum class InitFields : int32_t
{
userRightsPath = 1,
configurationDataPath,
configFile
};
static std::map<InitFields, QString> s_initField2str
{
{InitFields::rhSystem, "rhSystem"},
{InitFields::number, "number"},
{InitFields::userRightsPath,"userRightsPath"}
};
enum class UserRole : int32_t
{
Administrator=1,
Superuser,
Operator
};
static std::map<UserRole, QString> s_userRole2str
{
{UserRole::Operator, "Operator"},
{UserRole::Administrator,"Administrator"},
{UserRole::Superuser,"Super-User"}
};
'''
So my first option was trying to create just one function
'''
template <typename T>
static QString const toStr(T enumt)
{
QString value = "";
if (std::is_same<T, InitFields>())
{
value = s_initField2str[enumt];
}
else if (std::is_same<T, UserRole>())
{
value = s_userRole2str[enumt];
}
else
{
value = "Error converting the enum";
}
return value:
}
'''
While using this function I get compiling errors because the compiler resolves the type at compile time and there is always a type accesing a map that is not correct. I understand that.
So my second alternative was specializing toStr() with each enum type but I got multiple definitions while compiling.
'''
template <typename T>
static QString const toStr(T enumt)
{
return "Error converting the enum";
}
template <>
static QString const toStr<InitFields>(InitFields enumt)
{
return s_initField2str[enumt];
}
template<>
QString const toStr<UserRole>(UserRole enumt)
{
return s_userRole2str[enumt];
}
'''
Is what I'm trying even possible? Could you shed some light about this?
Many thanks
First options requires C++17 and if constexpr
:
template <typename T>
static QString const toStr(T enumt)
{
if constexpr (std::is_same<T, InitFields>())
{
return s_initField2str[enumt];
}
else if constexpr (std::is_same<T, UserRole>())
{
return s_userRole2str[enumt];
}
else
{
return "Error converting the enum";
}
}
So my second alternative was specializing toStr() with each enum type but I got multiple definitions while compiling.
template
are implicitly inline
, but not specialization, so you need inline
to avoid multiple definition:
template <typename T>
QString toStr(T enumt)
{
return "Error converting the enum";
}
template <>
inline QString toStr<InitFields>(InitFields enumt)
{
return s_initField2str[enumt];
}
template<>
inline QString toStr<UserRole>(UserRole enumt)
{
return s_userRole2str[enumt];
}
Alternative would be simple overloads:
template <typename T>
QString toStr(T enumt) // = delete;
{
return "Error converting the enum";
}
inline QString toStr(InitFields enumt)
{
return s_initField2str[enumt];
}
inline QString toStr(UserRole enumt)
{
return s_userRole2str[enumt];
}