为什么case语句只接受常量?

时间:2013-05-07 00:26:19

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

C ++中的switch语句必须用常量编写的原因是什么?

我们来看看以下代码:

switch(variable)
{
    case 1:
    case 2:
    case 3:
    case 4:
        //Code 1
        break;

    case 5:
    case 6:
    case 7:
    case 8:
        //Code 2
        break;

    default:
        //Code 3
        break;
}

在其他语言中,例如PAWN(C-Like脚本语言),我可以这样写下这段代码:

switch(variable)
{
    case 1 .. 4:
        //Code 1
        break;

    case 5 .. 8:
        //Code 2
        break;

    default:
        //Code 3
        break;
}

C ++ switch语句背后的原因是什么?来自石器时代? (更不用说我们不能使用变量。)

即使经过这么多年的这么多变化和更新......

3 个答案:

答案 0 :(得分:5)

没有技术原因无法更新C开关语句以使用范围。 gcc已经有了这个扩展。

http://www.n4express.com/blog/?p=1225

常量的原因很充分;它允许各种优化,例如跳转表。

答案 1 :(得分:1)

如果你不介意另一个查找,你可以生成一个表来简化你的case语句:

char the_case (unsigned variable) {
    static const char all_cases[] = {
        0,
        'A', 'A', 'A', 'A',
        'B', 'B', 'B', 'B',
    };
    if (variable < sizeof(all_cases)) return all_cases[variable];
    return 0;
}

//...
switch (the_case(variable)) {
case 'A':
    //...
    break;
case 'B':
    //...
    break;
default:
    //...
    break;
}

或者,您可以创建unordered_map函数指针或方法,其中键是variable类型。

答案 2 :(得分:1)

switch设计用于简单的表查找,Pascal case也是如此。 Pascal case支持的范围,我记得,与Pascal位集相同。 C也可以这样做,但无论出于何种原因,都没有。

并且对该功能的要求不足以使其成为标准,C或C ++。

关于案例标签的变量或非整数类型,这将改变语句的性质。 C和C ++根本不会拥有一般select语句。但是在C ++中你可以自己做饭:

template< class Key >
auto select(
    const Key&                          key,
    const map<Key, function<void()>>&   actions
    )
    -> bool
{
    const auto it = actions.find( key );
    if( it == actions.end() ) { return false; }
    it->second();  return true;
}

然后你可以写像

这样的东西
auto main() -> int
{
    cout << "Command? ";
    const string command = readline();
    select( command, map<string, function<void()>>
    {
        { "blah", []{ cout << "You said blah!\n"; } },
        { "asd",  []{ cout << "You said asd!?!\n"; } }
    } );
}

您可以根据需要轻松添加默认值,例如:使用or关键字。

嗯,有趣的是我之前没有想到这一点,但显然其他人都没有。 :)