编译时检查的字符串到int映射是否可行?

Cha*_*_99 6 c++ string map compile-time

我可能想要实现不可能的,但StackExchange总是让我感到惊讶,所以请你去看看:

我需要将名称映射到整数.名字(约2k)是独一无二的.该列表不会有任何添加或删除,并且这些值在运行时不会更改.

将它们作为const int变量实现,可以对存在和类型进行编译时检查.这在代码中也非常清晰和冗长.很容易发现错误.

实现它们为std::map<std::string, int>我提供了很大的灵活性来构建名称以查找字符串操作.我可以使用它来将字符串作为参数提供给函数,这些函数可以通过在该字符串后附加前缀/后缀来查询列表中的多个值.我还可以通过从循环变量创建键名的数字部分来循环遍历多个值.

现在我的问题是:是否有一种结合两种优势的方法?缺少编译时检查(特别是对于密钥存在)几乎杀死了我的第二种方法.(特别是如果密钥不存在,则会std::map无声地返回0,这会导致很难找到错误.)但循环和前/后缀添加功能非常有用.

我更喜欢不使用任何其他库(如boost)的解决方案,但请尽可能地建议它们,因为我可能无论如何都可以重新实现它们.

关于我对地图做什么的一个例子:

void init(std::map<std::string, int> &labels)
{        
  labels.insert(std::make_pair("Bob1" , 45 ));
  labels.insert(std::make_pair("Bob2" , 8758 ));
  labels.insert(std::make_pair("Bob3" , 436 ));
  labels.insert(std::make_pair("Alice_first" , 9224 ));
  labels.insert(std::make_pair("Alice_last" , 3510 ));
}

int main() 
{      
  std::map<std::string, int> labels;
  init(labels);

  for (int i=1; i<=3; i++)
  {
    std::stringstream key;
    key << "Bob" << i; 
    doSomething(labels[key.str()]);
  }

  checkName("Alice");
}

void checkName(std::string name)
{
  std::stringstream key1,key2;
  key1 << name << "_first";
  key2 << name << "_last";
  doFirstToLast(labels[key1.str()], labels[key2.str()]);
}
Run Code Online (Sandbox Code Playgroud)

另一个目标是main()例程中显示的代码尽可能简单和冗长.(需要非程序员理解.)该init()函数将由某些工具代码生成.该doSomething(int)功能是固定的,但我可以写身边的包装功能.类似的助手checkName() 可能更复杂,但需要易于调试.

bri*_*ing 1

实现示例的一种方法是使用枚举和标记粘贴,如下所示

enum {
  Bob1 = 45,
  Bob2 = 8758,
  Bob3 = 436,
  Alice_first = 9224,
  Alice_last = 3510
};

#define LABEL( a, b ) ( a ## b )

int main() 
{      

  doSomething( LABEL(Bob,1) );
  doSomething( LABEL(Bob,2) );
  doSomething( LABEL(Bob,3) );
}


void checkName()
{
  doFirstToLast( LABEL(Alice,_first), LABEL(Alice,_last) );
}
Run Code Online (Sandbox Code Playgroud)

这是否最好取决于名称的来源。

如果您需要支持 for 循环用例,请考虑

int bob[] = { 0, Bob1, Bob2, Bob3 }; // Values from the enum

int main() 
{      
  for( int i = 1; i <= 3; i++ ) {
    doSomething( bob[i] );
  }
}
Run Code Online (Sandbox Code Playgroud)