У меня есть следующий код:Как связать класс с перечислением?
#include <string>
enum class Hobbit {
// typedef HobbitHelper helper;
UNKNOWN = -1, Bilbo, Frodo, Samwise
};
struct HobbitHelper {
static Hobbit decode(std::string const& s) {
if (s == "Bilbo") {
return Hobbit::Bilbo;
}
else if (s == "Frodo") {
return Hobbit::Frodo;
}
else if (s == "Samwise") {
return Hobbit::Samwise;
}
else {
return Hobbit::UNKNOWN;
}
}
};
enum class Wizard {
// typedef Apprentice helper;
UNKNOWN = -1, Gandalf, Radagast, Saruman
};
struct Apprentice { // WizardHelper :)
static Wizard decode(std::string const& s) {
if (s == "Gandalf") {
return Wizard::Gandalf;
}
else if (s == "Radagast") {
return Wizard::Radagast;
}
else if (s == "Saruman") {
return Wizard::Saruman;
}
else {
return Wizard::UNKNOWN;
}
}
};
template <typename T>
T
decoder(std::string s)
{
return ??::decode(s);
// if the typedefs were allowed, I could use T::helper::decode()
}
int main()
{
std::string s{ "Rincewind" };
auto h = decoder<Hobbit>(s);
auto w = decoder<Wizard>(s);
}
Как я могу устроить, чтобы вызвать соответствующий вспомогательный класс (HobbitHelper или Apprentice) в decoder
? Я не могу объявить вложенный тип внутри перечисления, как если бы это был класс. Я также попытался получить хелпера из перечисления (поскольку сам помощник не имеет данных), но это тоже не допускается.
Любые идеи?
В то время как я вырос, чтобы не любить слово «помощник», это довольно элегантный ответ (поддержанный). – Jeff
Это решение также можно распространять: «template <> struct helper: type_is {};' специализации могут быть в соответствующем заголовке. Переименование 'helper_t' в' helper_of' делает его еще более мнемоничным. –
Bulletmagnet