Це рішення не вимагає використання будь-яких структур даних або створення іншого файлу.
В основному, ви визначаєте всі свої значення перерахування в #define, а потім використовуєте їх в операторі <<. Дуже схожий на відповідь @ jxh.
посилання ideone для остаточної ітерації: http://ideone.com/hQTKQp
Повний код:
#include <iostream>
#define ERROR_VALUES ERROR_VALUE(NO_ERROR)\
ERROR_VALUE(FILE_NOT_FOUND)\
ERROR_VALUE(LABEL_UNINITIALISED)
enum class Error
{
#define ERROR_VALUE(NAME) NAME,
ERROR_VALUES
#undef ERROR_VALUE
};
inline std::ostream& operator<<(std::ostream& os, Error err)
{
int errVal = static_cast<int>(err);
switch (err)
{
#define ERROR_VALUE(NAME) case Error::NAME: return os << "[" << errVal << "]" #NAME;
ERROR_VALUES
#undef ERROR_VALUE
default:
return os << errVal;
}
}
int main() {
std::cout << "Error: " << Error::NO_ERROR << std::endl;
std::cout << "Error: " << Error::FILE_NOT_FOUND << std::endl;
std::cout << "Error: " << Error::LABEL_UNINITIALISED << std::endl;
return 0;
}
Вихід:
Error: [0]NO_ERROR
Error: [1]FILE_NOT_FOUND
Error: [2]LABEL_UNINITIALISED
Приємна річ у тому, що ви робите це таким чином, що ви також можете вказати власні повідомлення для кожної помилки, якщо вважаєте, що вони вам потрібні:
#include <iostream>
#define ERROR_VALUES ERROR_VALUE(NO_ERROR, "Everything is fine")\
ERROR_VALUE(FILE_NOT_FOUND, "File is not found")\
ERROR_VALUE(LABEL_UNINITIALISED, "A component tried to the label before it was initialised")
enum class Error
{
#define ERROR_VALUE(NAME,DESCR) NAME,
ERROR_VALUES
#undef ERROR_VALUE
};
inline std::ostream& operator<<(std::ostream& os, Error err)
{
int errVal = static_cast<int>(err);
switch (err)
{
#define ERROR_VALUE(NAME,DESCR) case Error::NAME: return os << "[" << errVal << "]" #NAME <<"; " << DESCR;
ERROR_VALUES
#undef ERROR_VALUE
default:
return os << errVal;
}
}
int main() {
std::cout << "Error: " << Error::NO_ERROR << std::endl;
std::cout << "Error: " << Error::FILE_NOT_FOUND << std::endl;
std::cout << "Error: " << Error::LABEL_UNINITIALISED << std::endl;
return 0;
}
Вихід:
Error: [0]NO_ERROR; Everything is fine
Error: [1]FILE_NOT_FOUND; File is not found
Error: [2]LABEL_UNINITIALISED; A component tried to the label before it was initialised
Якщо вам подобається робити свої коди помилок / описи дуже описовими, можливо, ви не хочете, щоб вони були у виробничих збірках. Вимкнути їх, щоб надрукувати лише значення, легко:
inline std::ostream& operator<<(std::ostream& os, Error err)
{
int errVal = static_cast<int>(err);
switch (err)
{
#ifndef PRODUCTION_BUILD
#define ERROR_VALUE(NAME,DESCR) case Error::NAME: return os << "[" << errVal << "]" #NAME <<"; " << DESCR;
ERROR_VALUES
#undef ERROR_VALUE
#endif
default:
return os << errVal;
}
}
Вихід:
Error: 0
Error: 1
Error: 2
Якщо це так, знаходження помилки номер 525 було б ПДФО. Ми можемо вручну вказати числа в початковому переліку, як це:
#define ERROR_VALUES ERROR_VALUE(NO_ERROR, 0, "Everything is fine")\
ERROR_VALUE(FILE_NOT_FOUND, 1, "File is not found")\
ERROR_VALUE(LABEL_UNINITIALISED, 2, "A component tried to the label before it was initialised")\
ERROR_VALUE(UKNOWN_ERROR, -1, "Uh oh")
enum class Error
{
#define ERROR_VALUE(NAME,VALUE,DESCR) NAME=VALUE,
ERROR_VALUES
#undef ERROR_VALUE
};
inline std::ostream& operator<<(std::ostream& os, Error err)
{
int errVal = static_cast<int>(err);
switch (err)
{
#ifndef PRODUCTION_BUILD
#define ERROR_VALUE(NAME,VALUE,DESCR) case Error::NAME: return os << "[" #VALUE "]" #NAME <<"; " << DESCR;
ERROR_VALUES
#undef ERROR_VALUE
#endif
default:
return os <<errVal;
}
}
ERROR_VALUES
#undef ERROR_VALUE
#endif
default:
{
return os << static_cast<int>(err);
break;
}
}
}
Вихід:
Error: [0]NO_ERROR; Everything is fine
Error: [1]FILE_NOT_FOUND; File is not found
Error: [2]LABEL_UNINITIALISED; A component tried to the label before it was initialised
Error: [-1]UKNOWN_ERROR; Uh oh