Giải pháp này không yêu cầu bạn sử dụng bất kỳ cấu trúc dữ liệu nào hoặc tạo một tệp khác.
Về cơ bản, bạn xác định tất cả các giá trị enum của mình trong #define, sau đó sử dụng chúng trong toán tử <<. Rất giống với câu trả lời của @ jxh.
liên kết Ideone cho lần lặp cuối cùng: http://ideone.com/hQTKQp
Mã đầy đủ:
#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;
}
Đầu ra:
Error: [0]NO_ERROR
Error: [1]FILE_NOT_FOUND
Error: [2]LABEL_UNINITIALISED
Một điều thú vị khi làm theo cách này là bạn cũng có thể chỉ định các thông báo tùy chỉnh của riêng mình cho từng lỗi nếu bạn cho rằng mình cần chúng:
#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;
}
Đầu ra:
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
Nếu bạn muốn làm cho mã lỗi / mô tả của mình thật mô tả, bạn có thể không muốn chúng trong các bản dựng sản xuất. Việc tắt chúng để chỉ in giá trị thật dễ dàng:
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;
}
}
Đầu ra:
Error: 0
Error: 1
Error: 2
Nếu đúng như vậy, việc tìm lỗi số 525 sẽ là PITA. Chúng ta có thể chỉ định thủ công các số trong enum ban đầu như sau:
#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;
}
}
}
Đầu ra:
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