简体   繁体   English

在运行时设置矢量类型

[英]Set vector type at runtime

I have a program that needs to set the type of a vector as the program is executed (according to a value in a configuration file). 我有一个程序,需要在程序执行时设置向量的类型(根据配置文件中的值)。

I have tried this: 我试过这个:

int a = 1

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

test.push_back(3);

But this gives me: 但这给了我:

Error   1   error C2065: 'test' : undeclared identifier

I'm not entirely sure why, but I think this is because the vector is not actually decided at compile time so the compiler cannot work with it whilst compiling the rest of the code. 我不完全确定原因,但我认为这是因为矢量实际上并不是在编译时决定的,因此编译器在编译其余代码时无法使用它。

Is there a way to decide the type of a vector at runtime similar to what I have attempted above? 有没有办法在运行时决定向量的类型,类似于我上面尝试的? I have tried to create one version outside the if and then delete it and re-write the new version inside the IF. 我试图在if之外创建一个版本然后删除它并在IF中重新编写新版本。 This however feels wrong and I can't get it to work anyway. 然而这感觉不对,无论如何我无法让它工作。 thanks. 谢谢。

The reason it does not work is that you're declaring the vectors inside the if- and else-block respectively, so they go out of scope once that block ends. 它不起作用的原因是你分别在if-和else-block中声明了向量,因此一旦该块结束它们就会超出范围。

Is there a way to decide the type of a vector at runtime similar to what I have attempted above? 有没有办法在运行时决定向量的类型,类似于我上面尝试的?

No, the type of a variable must be known at compile-time. 不,必须在编译时知道变量的类型。 Your only option is to put the line test.push_back(3) as well as any following code which accesses test into the if- and the else-block, or to avoid code-duplication into a second templated function. 您唯一的选择是将test.push_back(3)行以及任何访问test以下代码放入if-和else-block,或者避免代码复制到第二个模板化函数中。 This could look like this: 这看起来像这样:

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);
    }
}

The exact reason for the error you are getting is kind of a subtle one for a beginner, and it involves the scope of the variable test that you are creating. 您获得错误的确切原因对于初学者来说是一种微妙的原因,它涉及您正在创建的变量test的范围。 Simply put, you are creating the vector inside of the if statement, but by the time you are going to use it, it no longer exists because it has gone out of scope. 简单地说,您正在if语句中创建向量,但是当您要使用它时,它不再存在,因为它已超出范围。

I have reformatted your code with brackets to make this effect more noticable. 我用括号重新格式化了你的代码,使这个效果更加明显。 Note that my version is semantically equivalent to yours and will give the same error. 请注意,我的版本在语义上与您的版本等效,并且会出现相同的错误。

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

test.push_back(3);

That said, what you are trying to do seems a little weird, and I have to wonder what your end goal is. 那就是说,你想要做的事情看起来有点奇怪,我不得不想知道你的最终目标是什么。 That is not to say that there are not ways to do what you seem to want to do, but I would need to know what your success criteria before I could suggest a more appropriate method. 这并不是说没有办法去做你似乎想要做的事情,但在我建议一个更合适的方法之前,我需要知道你的成功标准。

I'm not sure why do you need that but I suggest you to try to use a vector of union to solve your problem, something like this 我不确定你为什么需要这个,但我建议你尝试使用联合矢量来解决你的问题,就像这样

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

Or probably more elegant way is to use boost::variant instead of the union. 或者更优雅的方式是使用boost :: variant而不是union。 Maybe if you give us more details about your problem you get a much better asnwer. 也许如果你给我们更多关于你的问题的细节你会得到更好的asnwer。

Good luck! 祝好运!

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

Setting a vector's type (aka template instantiation ) always happens at compile time. 设置向量的类型(也称为模板实例化 )总是在编译时发生。 For more clarification check out the Wikipedia article on Template metaprogramming . 有关更多说明,请查看Wikipedia关于模板元编程的文章。

if you truly need a polymorphic Type, perhaps you could take a look at the boost::variant class or something similar; 如果你真的需要一个多态类型,也许你可以看看boost :: variant类或类似的东西;
This is designed to mimic some of the behavior of dynamic languages within C++, and is usually used for interfacing with (or implementing) them. 它旨在模仿C ++中动态语言的某些行为,通常用于与(或实现)它们进行交互。 you could create a "vector< Variant > a", and a.push_back(Variant((unsigned int)..). the constructors for values pushed need compile time type. 你可以创建一个“vector <Variant> a”和a.push_back(Variant((unsigned int)..)。推送值的构造函数需要编译时类型。

It would also be possible to make a vectorized variant class which stores the type information for the entire collection if you expected the values to be homogenous. 如果您期望值是同质的,那么还可以创建一个矢量化变体类来存储整个集合的类型信息。

but, it's far more likely you can acheive the desired end result without such a mechanism, reworking your program to avoid runtime type checks perhaps (which would most likely negate some of the benefits of using C++ over another language in the first place). 但是,如果没有这样的机制,你更有可能实现理想的最终结果,重新编写你的程序以避免运行时类型检查(这很可能会否定一开始使用C ++而不是其他语言的一些好处)。

You could write the type dependent parts as templates (as suggested above) and select an alternative code path based on the configuration file setting checked & dispatched once. 您可以将类型相关部分编写为模板(如上所述),并根据配置文件设置选择一个替代代码路径,并将其分派一次。 This style of coding gets slightly easier in c++0x with 'auto' and decltype() too. 使用'auto'和decltype(),这种编码风格在c ++ 0x中稍微容易一些。

The specific case of unsigned versus signed values involves allowing one more bit which sounds unusual, or of marginal benefit compared to the added complexity, but I can easily imagine one wanting an implementation that can switch between single and double precision float for example. 无符号与有符号值的具体情况涉及允许一个听起来不寻常的位,或者与增加的复杂性相比具有边际效益,但我可以很容易地想象一个想要在单精度和双精度浮点之间切换的实现。

Yet another simple option would be to make a compile time setting for the type (eg introduced as a define from the build settings or makefile), then distribute multiple versions of your program, which might make sense in some circumstances. 另一个简单的选择是为类型进行编译时设置(例如,作为构建设置或makefile中的定义引入),然后分发程序的多个版本,这在某些情况下可能有意义。 However, the templates already suggested are more likely to be the most useful option. 但是,已建议的模板更可能是最有用的选项。

In your example, you have independent instances of a variable test created in each branch of your if statement, each of which goes out of scope immediately. 在您的示例中,您在if语句的每个分支中创建了一个变量test独立实例,每个分支都立即超出范围。 So when the compiler gets to test.push_back(3); 所以当编译器进入test.push_back(3); there is no test variable in scope, hence the error. 范围内没有test变量,因此出错。

To address your problem, you can't fight the type system: assuming that int and unsigned int are the actual types in question you'd be much better off using vector<int> throughout, presuming that you don't actually need the full range of an unsigned int. 为了解决你的问题,你无法对抗类型系统:假设intunsigned int是有问题的实际类型,你最好总是使用vector<int> ,假设你实际上并不需要完整的unsigned int的范围。

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

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