如果/切换里面的声明

时间:2009-11-07 07:31:46

标签: c++

我正在尝试用C ++做这样的事情:

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

f(a);

但是我从编译器得到一个错误,指出a未在此范围内声明。 我需要做一个条件声明,我该怎么做?

非常感谢

编辑: 由于问题较大,我无法在条件内移动函数: F(A,B,C); 其中a,b和c需要以这种方式声明。

10 个答案:

答案 0 :(得分:5)

通过定义template function来实现您想要的一种方式。您可以定义模板,编译器将为您调用的每种类型编译函数的版本。

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

在这种情况下,T_my_type是模板参数,将隐式替换为您调用函数的参数类型。

C ++中的模板编程是一个相当大的蠕虫可以打开,正如其他人所建议的那样,我认为你可能需要重新考虑你的方法。

答案 1 :(得分:4)

看起来您希望根据条件结构中的路径调用不同的重载。这在C ++这样的静态语言中是不可能的,因为编译器需要决定在编译时调用哪个重载,并且每次调用只能选择一个。

请改为:

if (...) {
    int a = ...;
    f(a);
} else if (...) {
    char a = ...;
    f(a);
} else {
    double a = ...;
    f(a);
}

答案 2 :(得分:4)

C ++是一种静态类型语言。如果要处理变量,则必须在编译时知道其类型。如果你想要检查的条件在编译时也是已知的,那么可能有一个很好的解决方案涉及模板。如果if语句中的表达式依赖于运行时,则必须在声明。

的块内移动函数调用

答案 3 :(得分:3)

你可以使用工会。

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

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

我不知道f()会做什么,所以我不知道这是否适用于你的情况。正如其他人所说,模板是一种选择。或者您可以尝试使用类型转换而不是使用联合。

答案 4 :(得分:3)

请考虑一下:

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
}

答案 5 :(得分:2)

如果你必须在外面有f()并且不想使用联合,你可以考虑使用多态:

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

当然为了获得任何真正的OOP质量,您必须向Base类添加一些虚拟方法,并在继承类中实现它们以完成您需要完成的实际工作,否则您将在f()内的某处再次进行此切换,探测a的实际类型。

答案 6 :(得分:1)

您还可以将f()作为模板函数,并为不同的数据类型实现该函数。

f(模板类T) {

}

答案 7 :(得分:0)

如果可能,请为您的条件定义宏。这样你就可以使用这种语法

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

答案 8 :(得分:0)

你可以使用boost库。例如 1.提升::任何 boost :: any a;

a = std :: string(“A string”); 一个= 42; α= 3.1415;

F(一); 链接http://www.boost.org/doc/libs/1_40_0/doc/html/any.html

  1. 升压::变 boost :: variant a;
  2. A = 24; α= 2.52; A = “超赞!”; 一个= 0;

    F(一);

    链接http://www.boost.org/doc/libs/1_40_0/doc/html/variant.html

答案 9 :(得分:0)

使用void指针函数可以实现这一点。你只需要创建一个void *然后让它指向你选择的一个变量。然后你的函数可以简单地处理它的类型。例如:

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
}

注意,我没有测试过这段代码,因此它可能包含较小的语法错误,但会演示主体。