【问题标题】:C++11: Declare variable within switch statementC++11:在 switch 语句中声明变量
【发布时间】:2014-04-29 17:58:23
【问题描述】:

我知道 C++03 不允许在 switch 块中定义变量而不使用 花括号。

const int i = ...
switch (i) { case 0: int j = 0; break; } // 1. error here
switch (i) { case 0: { int j = 0; } break; } // 2. ok

关于新的 C++11 标准是什么? 它允许第一种形式吗? 我也可以这样写吗:

switch (i) 
{ 
  case 0: int j = 0; break; 
  case 1: int j = 0; break; 
  case 2: int j = 0; break; 
} 

【问题讨论】:

  • 不,还是要使用块。此外,您的第一个示例有点令人困惑,仅供参考。
  • 第一个例子有什么错误?在我看来很好。或者您的意思是在任何地方都使用i,而不是ij
  • 我只是想说我们有选择器 - i 并定义了另一个名为 distictly 的变量 - j

标签: c++ variables c++11 switch-statement definition


【解决方案1】:

case 语句没有(在 C++03 中)并且仍然没有(在 C++11 中)引入范围。

标准在[stmt.switch] (6.4.2/6) 中说:

case 和 default 标签本身不会改变 控制,在这些标签上继续畅通无阻。

因此它被允许“通过”case 这样的语句:

int x, a = 1;
switch(a) {
case 1:
    x = 5;
    // no break here!
case 10:
    x *= 4; // x is now 20.
}

例如,如果您在第一个 case 语句下方引入一个变量声明,则在跳转到第二个 case 语句时可能会跳过它。

但是,您可以在 switch 块的开头声明一个局部变量:

switch (i) 
{
    int j;
case 0: j = 0; break; 
case 1: j = 0; break; 
case 2: j = 0; break; 
}

switch 实际上更像是一个跳转表,而不是一系列 if/else if 语句。

【讨论】:

  • 我从来不知道你可以在第一个 case 标签之前声明变量。
  • @MarkRansom 你可以在那里拥有几乎任何东西 (switch (3) { puts("Huh?!"); }),这几乎没有用处,但变量声明是它有用的少数例外之一。
  • @MarkRansom:Duff's Device。如果您从未见过它,那么值得一看。本质上,您将 a 循环的主体与 switch 的主体交错,以便在跳过第一次迭代的一些可变数量的同时展开循环。
【解决方案2】:

C++03 当然允许你在 switch 语句的主体中定义变量。该主体与任何其他复合语句完全不同,跳转到标签的规则以相同的方式应用:您只能跳转到

的范围
  • 没有初始化器声明的标量类型
  • 具有平凡默认构造函数和平凡析构函数的类类型,在没有初始化器的情况下声明
  • 上述数组

这些规则在 C++11 中没有改变。

#include <iostream>
int main()
{
    int n;
    std::cin >> n;

    switch(n)
    {
               int a;      // okay, scalar with no initializer
       case 1: int b = 10; // okay, no more labels, no way jump into scope
               a = b = 3*n;
               break;
    }

【讨论】:

    【解决方案3】:

    由于范围问题,您无法编写此内容。您的代码将导致变量j的重新定义

    在您的代码中:

    const int i = ...
    switch (i) { case 0: int j = 0; break; } // the error should be linked to default statement that is not there
    switch (i) { case 0: { int j = 0; } break; } // here  you define a local scope in which you can define `j` ; j will be destroyed after the closing bracket.
    

    即使在 c++11 中,也尝试这样做:

    switch (i) 
    { 
      case 0: int j = 0; break; 
      case 1: int j = 0; break; 
      case 2: int j = 0; break; 
    } 
    

    导致与你想写的相同的错误:

    for ( ; ; ) {
          int i = 0 ;
          int i = 0 ;
          int i = 0 ;
    }
    

    这会导致重新定义错误

    【讨论】:

    • 这不是被禁止的原因,真正的原因见this question(跳过初始化)。
    猜你喜欢
    • 1970-01-01
    • 2010-11-16
    • 2010-11-10
    • 2020-12-27
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多