在运行时设置矢量类型

时间:2009-09-15 09:19:25

标签: c++ vector runtime types

我有一个程序需要在执行程序时设置向量的类型(根据配置文件中的值)。

我试过这个:

int a = 1

if(a == 1)  vector<int> test(6);
else  vector<unsigned int> test(6);

test.push_back(3);

但是这给了我:

Error   1   error C2065: 'test' : undeclared identifier

我不完全确定原因,但我认为这是因为在编译时实际上并没有决定向量,因此编译器在编译其余代码时无法使用它。

有没有办法在运行时决定矢量的类型,类似于我上面尝试过的? 我试图在if之外创建一个版本然后删除它并在IF中重新编写新版本。然而这感觉不对,无论如何我无法让它工作。 感谢。

7 个答案:

答案 0 :(得分:13)

它不起作用的原因是你分别在if-和else-block中声明了向量,因此一旦该块结束它们就会超出范围。

  

有没有办法在运行时决定向量的类型,类似于我上面尝试的那样?

不,必须在编译时知道变量的类型。您唯一的选择是将行test.push_back(3)以及访问test的任何后续代码放入if-和else-block,或者避免代码复制到第二个模板化函数中。这看起来像这样:

template <class T>
do_something_with_test(vector<T>& test) {
    test.push_back(3);
    // work with test
}

void foo() {
    int a = 1

    if(a == 1) {
        vector<int> test(6);
        do_something_with_test(test);
    }
    else {
        vector<unsigned int> test(6);
        do_something_with_test(test);
    }
}

答案 1 :(得分:4)

您获得错误的确切原因对于初学者来说是一种微妙的原因,它涉及您正在创建的变量test的范围。简单地说,您在if语句中创建了向量,但是当您要使用它时,它已不再存在,因为它已超出范围。

我已使用括号重新格式化您的代码,以使此效果更加明显。请注意,我的版本在语义上与您的版本等效,并且会给出相同的错误。

if(a == 1)
{
  vector<int> test(6);
}
else
{
  vector<unsigned int> test(6);
}

test.push_back(3);

那就是说,你要做的事似乎有点奇怪,我不得不想知道你的最终目标是什么。这并不是说没有办法做你似乎想要做的事情,但在建议更合适的方法之前,我需要知道你的成功标准。

答案 2 :(得分:3)

我不确定你为什么需要这个,但我建议你尝试使用联合矢量来解决你的问题,就像这样

union DataType
{
    int intVal;
    unsigned uintVal;
}
std::vector<DataType> vec;

或者更优雅的方式是使用boost::variant而不是联合。也许如果你给我们更多关于你的问题的细节,你会得到更好的asnwer。

祝你好运!

答案 3 :(得分:2)

你可以看看boost::any来实现类似的目标。

答案 4 :(得分:1)

设置向量的类型(又名模板实例化)总是在编译时发生。有关更多说明,请查看有关Template metaprogramming的维基百科文章。

答案 5 :(得分:0)

如果你真的需要一个多态类型,也许你可以看看boost :: variant类或类似的东西;
它旨在模仿C ++中动态语言的某些行为,通常用于与(或实现)它们进行交互。 你可以创建一个“vector&lt; Variant&gt; a”和a.push_back(Variant((unsigned int)..)。推送值的构造函数需要编译时类型。

如果您希望这些值是同质的,那么也可以创建一个矢量化变体类来存储整个集合的类型信息。

但是,如果没有这样的机制,你更有可能实现理想的最终结果,重新编写程序以避免运行时类型检查(这很可能会否定使用C ++而不是其他语言的一些好处) )。

您可以将类型相关部分编写为模板(如上所述),并根据选中的配置文件设置选择替代代码路径&amp;派遣一次。使用'auto'和decltype(),这种编码风格在c ++ 0x中稍微容易一些。

无符号与有符号值的具体情况涉及允许再多一点听起来不寻常,或者与增加的复杂性相比具有边际效益,但我可以很容易地想象一个想要在单精度和双精度浮点之间切换的实现,例如

另一个简单的选择是为类型进行编译时设置(例如,作为构建设置或makefile中的定义引入),然后分发程序的多个版本,这在某些情况下可能有意义。但是,已经建议的模板更有可能是最有用的选项。

答案 6 :(得分:-1)

在您的示例中,您在test语句的每个分支中创建了一个变量if的独立实例,每个实例都会立即超出范围。因此,当编译器到达test.push_back(3);时,范围内没有test变量,因此出错。

要解决您的问题,您无法对抗类型系统:假设intunsigned int是有问题的实际类型,那么在整个vector<int>使用{{1}}会更好,假设你实际上并不需要整个范围的unsigned int。