如何将字符串变量视为实际代码?

时间:2014-02-07 16:56:02

标签: c++ string function metaprogramming

这可能不太清楚。说我有char *a = "reg"。现在,我想编写一个函数,在读取a的值时,实例化特定类的对象并将其命名为reg

例如,假设我有一个class Register和一个单独的函数create(char *)。我想要这样的东西:

void create(char *s)  //s == "reg"
{
    //what goes here?
    Register reg;  // <- this should be the result
}

应该可以重复使用:

void create(char *s)  //s == "second"
{
    //what goes here?
    Register second;  // <- this should be the result
}

我希望我已经清楚了。基本上,我想将变量中的值视为单独的变量名。这在C / C ++中是否可行?如果不是,类似的东西?我目前的解决方案是散列字符串,哈希表将相关的Register对象存储在该位置,但我认为这是非常不必要的。

谢谢!

4 个答案:

答案 0 :(得分:4)

变量名称是编译时工件。它们在运行时不存在。在C ++中创建动态命名的变量是没有意义的。你会怎么称呼它?

假设您有这个假设的create函数,并编写了如下代码:

create("reg");
reg.value = 5;

这不会编译,因为编译器不知道第二行中reg引用了什么。

C ++没有任何方法可以在运行时查找变量,因此在运行时创建它们是不可能的。哈希表是正确的解决方案。将对象存储在哈希表中,并按名称查找它们。

答案 1 :(得分:2)

这是不可能的。 C ++在运行时不提供任何处理代码的工具。鉴于典型C ++实现的性质(提前编译机器代码,丢失有关源代码的所有信息),这甚至都不可行。

答案 2 :(得分:2)

就像我在评论中说的那样:
重点是什么?变量名是编译器的东西,但最重要的是 - ,程序员应该关心。一旦应用程序被编译,变量名称可能是任何...它可能被破坏和无意义,它不再重要。
您可以读/写代码,包括var-names。编译完成后,由硬件来处理它。

C和C ++都没有eval函数

仅仅因为:您只编译了您需要的内容,eval意味着稍后输入可能没有意义的内容,或者需要其他依赖项。 C / C ++是提前编译的,eval意味着在运行时进行评估。然后,C进程意味着:预处理,编译和链接字符串,使其仍然是当前进程的一部分...
即使有可能,eval总是被认为是邪恶的,对于像C系列这样意味着可靠运行的语言而言,这种情况会增加一倍,并且通常用于时间关键的操作。适合工作的正确工具以及所有......

包含hashkeyRegistercollision成员的对象的HashTable是明智之举。无论如何,开销并不是那么多......

还是觉得你需要这个吗?

查看大量的脚本语言。 Perl,Python ......他们都更适合做这种类型的东西

答案 3 :(得分:1)

如果您需要一些变量创建和查找,您可以:

  • 按照其他人的建议使用其中一种脚本语言
  • 自己明确地进行查找。最简单的方法是使用一个map,它将字符串映射到您的寄存器对象。然后你可以:
std::map<const char*, Register*> table;

Register* create(const char* name) {
    Register* r = new Register();
    table[name] = r;
    return r;
}

Register* lookup(const char* name) {
    return table[name];
}

void destroy(const char* name) {
    delete table[name];
    table.erase(name);
}

显然,每次要访问以这种方式创建的变量时,都必须通过调用lookup