views:

271

answers:

6

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. This however feels wrong and I can't get it to work anyway. thanks.

+4  A: 

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. 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.

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.

1800 INFORMATION
Thanks. NB: the code shown is just to explain... the actual program processes binary data and can run in 32 or 64 bit mode. The type of vector needs to change to hold pointers of either 64 or 32 bit size that point to a class (that actually holds the data). This class is a template class and so the type of my vector decides the type of my template class. I see what you're both saying about scope.I'm currently experimant to see if its possible to set the vector outside the if and then cast it up to 64 bit in the if loop.
Columbo
Why are you writing two lots of code to handle 32 or 64 bit? The compiler switch you use to control 32/64 version will determine the size and type of pointers - just have a vector of pointers-to-your-class, e.g. vector<my_class *> test;
JBRWilkinson
+12  A: 

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.

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. 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);
    }
}
sepp2k
Thanks. I see what you're saying. I'm going to look into this and maybe put all my code beyong the vector type descision into a templated function like you suggest.
Columbo
That worked, took a bit of shifting around bu that's sorted it. Thanks.
Columbo
+2  A: 

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. Maybe if you give us more details about your problem you get a much better asnwer.

Good luck!

Serge
Fixed your formatting so that "<DataType>" shows up in "vector<DataType>".
j_random_hacker
A: 

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. So when the compiler gets to test.push_back(3); there is no test variable in scope, hence the error.

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.

tragomaskhalos
+1  A: 

Setting a vector's type (aka template instantiation) always happens at compile time. For more clarification check out the Wikipedia article on Template metaprogramming.

StackedCrooked
+2  A: 

You could have a look at boost::any to achieve something similar.

larsm