tags:

views:

216

answers:

9

I'm trying to do something like this in C++:

if(){
    int a;
} else if(){
    char a;
} else {
    double a;
}

f(a);

But I get an error from the compiler saying that a was not declared in this scope. I need to do a conditional declaration, how can I do it?

Many thanks

edit: I cannot move the function inside the conditional as the problem is bigger: f(a,b,c); where a, b and c need to be declared in this way.

+5  A: 

It appears that you want different overloads to be called depending on the path taken through the conditional structure. This is not possible in a static language like C++ because the compiler needs to decide which overload to call at compile time, and can only pick one for each call.

Do this instead:

if (...) {
    int a = ...;
    f(a);
} else if (...) {
    char a = ...;
    f(a);
} else {
    double a = ...;
    f(a);
}
romkyns
Sorry, I should have specified that the problem is bigger, as I need several of this kind of variables for the same function.
Gerardo
Then you simply can't do it and need to figure out an alternative way.
Blindy
+3  A: 

C++ is a statically typed language. If you want to deal with a variable its type must be known at compile-time. If the conditions you want to check for are also known at compile-time there's probably a nice solution involving templates. If the expressions in your if statements are runtime dependent you have to move the function call inside the blocks that declare a.

sellibitze
A bit of a nitpick, but strictly speaking static _typing_ is not the same as permanently binding to a single overload of a function at compile time (although it wpould seem that the latter requires the former).
romkyns
+1  A: 

You can also make f() as template function and implement the function for different data types.

f(template class T) {

}

Vivek
+3  A: 

you could use a union.

union my_type
{
   int i;
   char c;
   double d;
}

my_type a;
if(){
    a.i = ...;
} else if(){
    a.c = ...;
} else {
    a.d = ...;
}
f(a);

I don't know what f() will be doing, so I don't know if this will work in your situation. As someone else stated, templates are one option. Or you could try just type-casting instead of using a union.

Matthew
You'd need an extra field so that f() knows which type to choose.
RedGlyph
@RedGlyph Depending on what f() does and/or how a is used, it might not be necessary. But most likely you would need it. Another reason why templates would probably be a better choice.
Matthew
+3  A: 

Consider this instead:

union T
{
  int i;
  double d;
  char c;
}

void process()
{
  T t;
  if(....) { work with t.i }
  else if(....) { work with t.d }
  else if(....) { work with t.c }

  f(t);
}

void f(T t)
{
  // now you have all your possible answers inside one variable
  // you might need to send a 2nd flag to mark the actual type inside
  // depending on your problem however, you might not need it

  // work with t.i, t.d or t.c
}
Blindy
+2  A: 

If you must have f() on the outside and don't want to use unions, you can consider polymorphism:

class Base {};
class AInt : public Base { int a; };
class AChar : public Base { char a; };
class ADouble : public Base { double a; };

Base *p = NULL;
if(){
    p = new AInt();
} else if(){
    p = new AChar();
} else {
    p = new ADouble();
}

f(a, b, c);

Ofcourse for this to have any real OOP quality you'll have to add some virtual methods to the Base class and implement them in the inheriting class to do the actual work you need be done or else you'll have this switch again somewhere inside f(), probing the real type of a.

shoosh
+3  A: 

One way of doing what you seem to want is by defining a template function. You define the template and the compiler will compile versions of the function for each type you call it with.

template <typename T_my_type> T_my_type MyTemplateFunction(T_my_type a)
{
  a++;
  std::cout << a;
  return a;
}

if(){
    int a;
    MyTemplateFunction(a);
} else if(){
    char a;
    MyTemplateFunction(a);
} else {
    double a;
    MyTemplateFunction(a);
}

In this case T_my_type is the template parameter and will be implicitly replaced with the type of the parameter that you call the function with.

Template programming in C++ is a rather large can of worms to open though, and as others have suggested, I think you may need to rethink your approach.

therefromhere
A: 

If it possible, define macros for your conditions. In that way you can use this syntax

#if defined(CONDITION1)
    int a;
    f(a);
#elif defined(CONDITION2)
    char a;
    f(a);
#elif defined(CONDITION3)
    double a;
    f(a);
#endif
Davit Siradeghyan
A: 

you can use boost library. For example 1. Boost::Any boost::any a;

a=std::string("A string"); a=42; a=3.1415;

f(a); Link http://www.boost.org/doc/libs/1%5F40%5F0/doc/html/any.html

  1. Boost::Variant boost::variant a;

a=24; a=2.52; a="Fabulous!"; a=0;

f(a);

Link http://www.boost.org/doc/libs/1%5F40%5F0/doc/html/variant.html

Davit Siradeghyan