0

您可以将函数调用作为案例语句标签吗?例如:

char x

switch(x)
{
   case isCapital():
      capitalcount++;
      break;

   case isVowel():
      vowelcount++;
      break;
   .
   .
   .
   .
   .

}

这在 C++ 中是否允许?

4

3 回答 3

4

案例标签中的值需要是一个常量表达式。也就是说,您直接问题的答案是:是的,您可以在 case 标签中调用某些函数。但是,不是您尝试调用的那些。但是,您可以让多个标签引用一组语句:

case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
    do_vowels();
    break;
于 2012-12-18T01:44:36.793 回答
4

我知道这本身并不能回答您的问题,但是您可以尝试像这样对其进行编码....

capitalcount += isCapital(x);
vowelcount += isVowel(x);

isXXX() 函数的布尔返回类型将被提升为 int 并作为 0 (false) 或 1 (true) 添加到计数中。

于 2012-12-18T01:45:08.713 回答
0

首先:在您想要的代码中isCapitalisVowel不应该是函数(当然也不是函数调用),而是函子——因为要检查一个值,他们必须通过参数接收它......

无论如何,您的代码在 C++ 中是不可能的......但可以用一系列函数对来模拟:谓词 + 效果。谓词必须接受一些参数并以布尔值响应。如果谓词是,效果会做true。要模拟中断和回退到下一个case(即当没有中断时case效果函数还必须返回一个布尔值。

示例代码可能如下所示:

#include <cctype>
#include <functional>
#include <iostream>
#include <vector>

int main(int argc, char* argv[])
{
    typedef std::vector<
        std::pair<
            std::function<bool(char)>       // predicate
        , std::function<bool()>             // effect: return true if `break' required
        >
    > case_seq_t;

    unsigned digits = 0;
    unsigned upper = 0;
    unsigned lower = 0;
    unsigned total = 0;
    unsigned other = 0;
    case_seq_t switch_seq = {
        {
            // predicate lambda can be replaced by std::bind
            // in this simple case... but need to change param type.
            // std::bind(&std::isdigit, std::placeholders::_1)
            [](char c) { return std::isdigit(c); }
          , [&]() { digits++; return true; }
        }
      , {
            [](char c) { return std::islower(c); }
          , [&]() { lower++; return true; }
        }
      , {
            [](char c) { return std::isupper(c); }
          , [&]() { upper++; return true; }
        }
        // `default` case
      , {
            [](char c) { return true; }
          , [&]() { other++; return true; }
        }
    };

    for (int i = 1; i < argc; i++)
        for (int pos = 0; argv[i][pos]; pos++)
            for (const auto& p : switch_seq)
                if (p.first(argv[i][pos]))
                    if (p.second())
                        break;

    std::cout << "digits=" << digits << std::endl;
    std::cout << "upper=" << upper << std::endl;
    std::cout << "lower=" << lower << std::endl;
    std::cout << "other=" << other << std::endl;
    return 0;
}

不是那么简单,switch但(恕我直言)足够明显......并且在某些实际情况下,可能具有更好的灵活性(并且可能具有可维护性):)

于 2012-12-18T03:37:37.817 回答