Link to home
Start Free TrialLog in
Avatar of LuckyLucks
LuckyLucks

asked on

declaring vector type based on size in switch statement

Hi

I would like to declare a vector but its type (whether char, float etc) needs to be determined based on the results of a switch statement.

switch(a){

     case 8:
     {
        std::vector<unsigned char> my_vector; break;
     }
     
    case 16:
    {

        std::vector<unsigned short> my_vector;break;
     }

     case  32:
     {

          std::vector<float> my_vector;break;
      }

    default:
    {
          std::vector<unsigned char> my_vector; break;
     }
}

my_vector.insert(my_vector.begin()+offset,myvalue);

but later down , after the switch statement ends,in the same function , when i try to perform an insert operation on my_vector, i get 'my_vector' :undeclared identifier.

what can i do to ensure that i have a my_vector that is created based on the results of the switch statement?
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of HooKooDooKu
HooKooDooKu

Simply put, variables can not be declared within a switch statement EXCEPT for variables that will have a scope of a single case (and the case must have {} around it:
switch(i)
{
  case 0:
  {
    int j=0;
    //... do stuff with j
  } //j goes out of scope here
}

Open in new window


About the only way I can thing to accomplish what you want to do is to use a pointer or a union.  

If you use a union, then you could use the switch statement to decide which data type within the union to process within the switch statement.

My personal approach would be to define a class and declare a pointer to that class.  Then inside the switch statement, create a new instance of the class where you could pass a parameter to the constructor to determine which 'mode' to create the class.
class myvectors
{
public:
  enum mode
  {
    CharMode,
    ShortMode,
    FloatMode
  ]
  mode m_mode;
  (std::vector<char>)* m_pChar;
  (std::vector<short>)* m_pShort;
  (std::vector<float>)* m_pFloat;
  myvector(mode){
    m_mode = mode;
    m_pChar = NULL;
    m_pShort = NULL;
    m_pFloat = NULL;
    switch( m_mode )
    {
      case CharMode: m_pChar = new std::vector<char>; break;
      case ShortMode: m_pShort = new std::vector<short>; break;
      case FloatMode: m_pFloat = new std::vector<float>; break;
    {;
};

Open in new window

From there, you would directly work with the vector that currently has a value, or when the functionality is the same regardless of the vector used, create a member function that looks at mode and determines which member variable to operate on.

I'm sure there might be some additional options if you started getting into templates.  But again, even there you basically can not change the declaration of a variable within a switch statement.  (In other words, you can change how a variable expresses itself within a switch statement, but you can't change how it is declared)
You can't do this. First of all when you define a variable inside the {...} block it is called that it is declared inside the scope of this block. So, the statement like this:
 {
        std::vector<unsigned char> my_vector; break;
 }

Open in new window

will only exist inside the {...} brackets. That is why you are getting these errors.
The my_vector variable has to be defined in the scope of the code you are going to use, in your case, in the beginning of the program.
To address your problem you have a few options:
1. Define my_vector as a type that is guaranteed to hold all possible values, e.g. double. Then just cast to the type you want inside your switch statement. However, please note that due to double's rounding problems you can experience some unexpected problems when casting the values to/from float.
2. Create a class that will use the type value and a union with different types. Then create the vector using this class. Here is a small example:
class Universal
{
public: 
  union val
  {
    float f;
    unsigned short us;
    unsigned char uc;
  } value;
  int type;
  Universal()
  SetType(int t){type = t;};
  SetFloat(float f)(value.f = f;);
  etc...
};

Open in new window

Now, you can define my_vector as  std::vector<Universal> my_vector;
3. You can define the vector as
 std::vector<void*> my_vector;
and populate the values like this:
 std::vector<void*> my_vector;
switch(a){
    case 16:
    {
        // b is a value you want to insert
        my_vector.push_back(new float(b));break;
     }

Open in new window

Please note that in this case you need to delete every element you are inserting using delete operator:
 while (!my_vector.empty())
  {
    delete my_vector.back();
    my_vector.pop_back();
  }

Open in new window

There are some other options, and I am pretty sure other experts give you their own answers....
Is the value of the variable 'a' known at compile time? If so this is easy to do with a little bit of template trait magic. If not, see above.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial