是否可以用 if 声明自动变量?
Is it possible to declare auto variables with an if?
我的代码在下面。
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 。
它发生了一个错误:
宣言
variable 'conv_desc' with deduced type 'auto' requires an initializer
或者如果我像下面这样使用指针,我得到一个空指针。
另一种方式出错:
Taking the address of a temporary object of type 'conv::des'
如果我不能解决这个问题,我将不得不在每个分支中写一大段重复的代码。
不要使用自动。如果需要声明一个变量,还不能赋值,那就不能用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;
}
将您的 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;
}
如果将 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;
}
您也可以使用立即调用的 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;
}
您似乎让代码过于复杂了。不清楚为什么要以这种方式区分这三个构造函数。为什么不使用这样的默认值来隐藏对象内部的复杂性?
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;
}
我的代码在下面。
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 。 它发生了一个错误: 宣言
variable 'conv_desc' with deduced type 'auto' requires an initializer
或者如果我像下面这样使用指针,我得到一个空指针。
另一种方式出错:
Taking the address of a temporary object of type 'conv::des'
如果我不能解决这个问题,我将不得不在每个分支中写一大段重复的代码。
不要使用自动。如果需要声明一个变量,还不能赋值,那就不能用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;
}
将您的 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;
}
如果将 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;
}
您也可以使用立即调用的 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;
}
您似乎让代码过于复杂了。不清楚为什么要以这种方式区分这三个构造函数。为什么不使用这样的默认值来隐藏对象内部的复杂性?
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;
}