【发布时间】:2013-09-01 14:16:36
【问题描述】:
我可能正在努力实现不可能的目标,但 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()]);
}
另一个目标是main() 例程中显示的代码尽可能简单和详细。 (需要非程序员理解。)init() 函数将由某些工具代码生成。 doSomething(int) 函数是固定的,但我可以围绕它们编写包装函数。像checkName() 这样的助手可能更复杂,但需要易于调试。
【问题讨论】:
-
听起来你想在运行时构造字符串,但不知何故在编译时检查了这个?
-
有一些方法可以将枚举转换为适当的字符串,所以应该是可能的。虽然如果你在运行时构建字符串,很难看出它是如何编译的
-
如果你想知道值是否在地图中,你不应该使用
map[index]!您可以使用map.find(index)获取对象的迭代器,或者使用map.end()(如果不存在)或map.at(index)在访问不存在的元素时获取异常。 -
我认为你可以用很多元编程魔法来做到这一点。关键是很难(但可能)在类型名称中编码字符串。老实说,我不建议这样做,因为编译可能需要数年时间(每个编译器对可变参数模板参数的数量都有最大限制,可能
-
@Chaos_99 有很多方法可以做到这一点。我们需要更多地了解您的代码才能选择最好的。枚举和令牌粘贴将是运行时最快的。
标签: c++ string map compile-time