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

时间:2019-03-27 12:07:39

标签: c++ auto

我的代码在下面。

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'的临时对象的地址

如果我不能解决此问题,则必须在每个分支中编写大量重复代码。

5 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:2)

您还可以使用立即调用的lambda。这是一种常见的模式,可以使某些变量在无法通过其他方式变为const时成为常量。

此解决方案与@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;
}

答案 2 :(得分:1)

不使用自动。如果您需要声明一个变量并且还不能赋值,那么就不能使用auto。

    Vue.component('show-title', {
        mounted(){
        fetch('https://jsonplaceholder.typicode.com/todos/1')
        .then(response => response.json())
        .then(json => this.title = json.title);
      },
        data: function () {
        return {
          title: "hello world!"
        }
      },
      template:"<h3>{{title}}</h3>"
    });
    new Vue({
      el: "#app",
      data: {
      },
      methods: {
      }
    })

您不能使用这样的指针

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以前的地址,现在不再有效。

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

b

答案 3 :(得分: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;
}

答案 4 :(得分: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;
}