繁体   English   中英

在运行时设置矢量类型

[英]Set vector type at runtime

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

我试过这个:

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中重新编写新版本。 然而这感觉不对,无论如何我无法让它工作。 谢谢。

它不起作用的原因是你分别在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);
    }
}

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

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

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

test.push_back(3);

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

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

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

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

祝好运!

你可以看看boost :: any来实现类似的东西。

设置向量的类型(也称为模板实例化 )总是在编译时发生。 有关更多说明,请查看Wikipedia关于模板元编程的文章。

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

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

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

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

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

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

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

为了解决你的问题,你无法对抗类型系统:假设intunsigned int是有问题的实际类型,你最好总是使用vector<int> ,假设你实际上并不需要完整的unsigned int的范围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM