0

関数呼び出しを case ステートメント ラベルとして使用できますか。例えば:

char x

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

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

}

これは C++ 内で許可されていますか?

4

3 に答える 3

4

ケース ラベルの値は、定数式である必要があります。つまり、当面の質問に対する答えは、はい、case ラベルで特定の関数を呼び出すことができるということです。ただし、呼び出しようとしたものではありません。ただし、複数のラベルで 1 つのステートメント グループを参照できます。

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() 関数の boolean 戻り型は int に昇格され、0 (偽) または 1 (真) としてカウントに追加されます。

于 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が、(IMHO)十分に明らかです...そして、実際のケースでは、より優れた柔軟性(およびおそらく保守性)があるかもしれません:)

于 2012-12-18T03:37:37.817 に答える