Declaration inside if/switch
I'm t开发者_运维百科rying 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.
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.
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);
}
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.
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.
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
}
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
.
You can also make f() as template function and implement the function for different data types.
f(template class T) {
}
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_40_0/doc/html/any.html
- Boost::Variant boost::variant a;
a=24; a=2.52; a="Fabulous!"; a=0;
f(a);
Link http://www.boost.org/doc/libs/1_40_0/doc/html/variant.html
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
This is possible with a void pointer taking function. You would simply have to create a as a void* then have it point to one of your chosen variables. Then your function can simply handle which type it is. For example:
void *a;
int b;
char c;
double d;
char typeofa;
if(foo == 1){
a = &b;
typeofa = 0;
} else if(foo == 2){
a = &c;
typeofa = 1;
} else {
a = &d
typeofa = 2;
}
int bar(void* a, char typeofa)
{
//etc, do right thing dependant on typeofa
//casting a to right type then dereferencing
}
Note, I have not tested this code so it may contain minor syntax errors but demonstrates the principal.
精彩评论