是否可以使用if声明自动变量?

问题描述 投票:-5回答:5

我的代码如下。

struct conv{
    struct des
    {
        des(int a) {}
        des(int a, int b) {}
        des(int a, int b, int c) {}
    };
};
int main(int argc, const char * argv[]) {

int a = 1;
int b = 1;
int c = 1;

if (a > 1)
{
    auto conv_desc = conv::des(1, 2, 3);
} else if(b > 1) {
    auto conv_desc = conv::des(1, 2);
} else {
    auto conv_desc = conv::des(1);
}
    return 0;
}

代码的模式是从mkldnn中提取的。我唯一想做的就是从if-else语句中取出auto conv_desc。我试图从if-else语句中声明auto conv_desc。它发生了一个错误:声明

带有推导类型'auto'的变量'conv_desc'需要初始值设定项

或者,如果我使用下面的指针,我得到一个空指针。 enter image description here

另一种方式出错:enter image description here

获取'conv :: des'类型的临时对象的地址

如果我无法解决这个问题,我将不得不在每个分支中写一大段重复的代码。

c++ auto
5个回答
4
投票

将您的if代码移动到单独的函数中:

conv::des make_des(int a, int b) {
  if (a > 1) {
    return conv::des(1, 2, 3);
  } else if(b > 1) {
    return conv::des(1, 2);
  } else {
    return conv::des(1);
  }
}

int main(int argc, const char * argv[]) {
  int a = 1;
  int b = 1;
  int c = 1;
  auto conv_desc = make_des(a, b);
  return 0;
}

2
投票

您也可以使用立即调用的lambda。这是一种常见的模式,可以在某些变量不可能的情况下使其成为常量。

这个解决方案与@yachoor回答非常相似,但使用的是lambda。

int main(int argc, const char * argv[]) {
    int a = 1;
    int b = 1;
    int c = 1;

    // Kind of an inline function that is called immediately
    auto const conv_desc = [&]{
        if (a > 1) {
            return conv::des(1, 2, 3);
        } else if(b > 1) {
            return conv::des(1, 2);
        } else {
            return conv::des(1);
        }
    }();
    // Parens calls the function

    return 0;
}

1
投票

如果将if ... else链移动到单独的函数中,则可以使用return

struct conv
{
    struct des
    {
        des(int a) {
        }

        des(int a, int b) {
        }

        des(int a, int b, int c) {
        }
    };
};

conv::des make_conv_des(int a, int b)
{
    if (a > 1) {
        return conv::des(1, 2, 3);
    } else if(b > 1) {
        return conv::des(1, 2);
    } else {
        return conv::des(1);
    }
}

int main(int argc, const char * argv[]) {

    int a = 1;
    int b = 1;

    auto conv_des = make_conv_des(a, b);

    return 0;
}

1
投票

好像你使代码过于复杂。目前尚不清楚为什么要以这种方式区分这三种构造函数。为什么不使用这样的默认值来隐藏对象内部的复杂性?

struct conv{
    struct des
    {
        des(int a, int b = 0, int c = 0) {
          if(a > 1) {
            /// do some logic
          } else if(b > 1) {
            // do some logic
          } else {
            // do some logic
          }

        }
    };
};
int main(int argc, const char * argv[]) {

  int a = 1;
  int b = 1;
  int c = 1;

  auto conv_desc = conv::des(a, b, c);

  return 0;
}

1
投票

不要使用汽车。如果您需要声明一个变量并且还无法分配值,则无法使用auto。

int main(int argc, const char * argv[]) {
    // ...
    conv::des conv_desc; // calls default constructor.

    if (a > 1)
    {
        conv_desc = conv::des(1, 2, 3);
    } else if(b > 1) {
        conv_desc = conv::des(1, 2);
    } else {
        conv_desc = conv::des(1);
    }
    // conv_desc is initialized at this point.
    return 0;
}

你不能使用像这样的指针

int *a;
{ // new scope
    int b = 5;
    a = &b; // error.
}
// b is no longer in scope here

b超出范围时,a将指向b曾经的地址,现在不再有效。

如果你想使用指针,那么你可以使用new。但是,在这种情况下,您必须在之后释放内存。

int main(int argc, const char** argv)
{
    conv::des *conv_desc = nullptr; // does not call default constructor.

    if (a > 1)
    {
        conv_desc = new conv::des(1, 2, 3);
    } else if(b > 1) {
        conv_desc = new conv::des(1, 2);
    } else {
        conv_desc = new conv::des(1);
    }
    if (conv_desc == nullptr) { /* memory allocation failed */ }
    // conv_desc is initialized at this point.
    // ...
    // remember to delete conv_desc
    if (conv_desc != nullptr) { delete conv_desc; conv_desc = nullptr; }
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.