首先你需要(文件)枚举值(该计划)和字符串之间的映射。它可能只是以十进制表示的整数值。或者例如枚举成员名称。
名称具有可读性好的优点,尤其是当它们是英文的时候,但缺点是它们需要一些额外的机器以及开发和维护工作。定义名称字符串
的一种方法是简单地使用名字的阵列,以及用于些许的完整性检查检查该数组的大小等于枚举值的数目:
#include <iostream>
#include <stdexcept> // std::exception, std::runtime_error
#include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS
#include <string>
namespace my {
using std::ios;
using std::istream;
using std::string;
struct Weekday
{
enum Enum{ monday, tuesday, wednesday, thursday, friday, saturday, sunday };
static Enum constexpr first_value = monday;
static Enum constexpr last_value = sunday;
static int constexpr n_values = last_value + 1;
static
auto identifiers() -> char const* const (&)[n_values]
{
static char const* const the_identifiers[] =
{ "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" };
return the_identifiers;
}
};
可替代地,预处理器或通用代码生成可用于生成相应的枚举值名称和名称字符串,但恕我直言,这是更值得的工作。
使用可用的名称,您只需要支持>>
即可定义合适的operator>>
,例如,如下:
istream& operator>>(istream& stream, Weekday::Enum& value)
{
string name;
if(stream >> name)
{
for(int i = 0; i < Weekday::n_values; ++i)
{
if(name == Weekday::identifiers()[i])
{
value = Weekday::Enum(i);
return stream;
}
}
stream.setstate(ios::failbit);
}
return stream;
}
} // namespace my
这里我选择使用相同的故障报告与标准的输入操作,通过流状态即。或者可以使用例外。然而,正如我所看到的,例外属于更高层次,例如在调用代码中:
using namespace std;
void cpp_main()
{
my::Weekday::Enum day;
cout << "Day? ";
cin >> day;
if(!cin) { throw runtime_error("Not a valid weekday name."); }
cout << "You chose a " << my::Weekday::identifiers()[day] << "." << endl;
}
auto main() -> int
{
try
{
cpp_main(); return EXIT_SUCCESS;
}
catch(exception const& x)
{
cerr << "!" << x.what() << endl;
}
return EXIT_FAILURE;
}
就是这样,除了优化。字符串查找可以通过将字符串放在std::map
或std::unordered_map
中进行优化。但是对于流I/O来说,主要的时间消费者是I/O,所以对查找的任何优化都可能不会产生任何显着的整体性能改进。
注:用Visual C++ 12.0编译这个,不支持constexpr
,使用/D constexpr=const /D _ALLOW_KEYWORD_MACROS
。
请参阅:[如何将枚举类型变量转换为字符串?](http://stackoverflow.com/questions/5093460/how-to-convert-an-enum-type-variable-to-a-string ) - 你也可以走相反的路。 – Vector 2014-10-05 23:40:59
@Vector我不知道这是可能的另一种方式,我绝对会读这个吧!谢谢! – SiggyxLeGiiT 2014-10-05 23:43:12
当你说你的文件格式的武器,我假设你的意思是相当于整数,而不是作为一个字符串的枚举名称,对不对? – Kevin 2014-10-06 02:43:32