2012-12-18 4 views
0

case 문 레이블로 함수 호출을 사용할 수 있습니까? 예 :case 문 레이블에서 함수 호출 사용

char x 

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

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

} 

C++에서 허용됩니까?

+7

시도하면 어떻게됩니까? 실제로 작동하는지 여부를 알아 내기 위해 실제로 실험 할 수 있습니다. 그것은 프로그래머들이 수십 년 동안 일을 배웠던 방식입니다. –

+0

@KenWhite - 프로그래밍이 Stack Overflow에서 발명되었다고 생각 했습니까? – Aesthete

+0

@Aesthete - 그건 소련 러시아에 없습니다. – Carl

답변

4

사례 레이블의 값은 상수 표현식이어야합니다. 즉, 즉각적인 질문에 대한 답변은 : 예, 사례 레이블에 특정 기능을 호출 할 수 있습니다. 그러나, 당신이 전화하려고 시도하지 않습니다. 여러 레이블하지만 문 한 그룹을 참조 할 수 있습니다 : .... 나는이 자체 귀하의 질문에 대답하지 않습니다 알고

case 'a': 
case 'e': 
case 'i': 
case 'o': 
case 'u': 
    do_vowels(); 
    break; 
4

,하지만 당신은 이런 식으로 코딩 시도 할 수

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

isXXX() 함수의 불린 반환 유형은 int로 승격되어 0 (거짓) 또는 1 (참)으로 카운트에 추가됩니다. 모든

+3

이것은 작동하지만 가독성을 위해 함수의 결과를 부울 데이터 유형으로 사용한다고 말하면 'capitalCount + = isCapital (x)? 1 : 0' – Jack

+2

@ 잭 - 그것은 "관용적"인 것들 중 하나입니다. 코드는 어디에서나 볼 수 있습니다. 일반적인 숙어를 받아들이고 간결한 코드를 작성하거나 일반적인 숙어를 피하고 좀 더 가독성이 있다고 생각하는 코드를 작성하고 다른 코드가 복잡하다고 생각하는 코드를 작성할 수 있습니다. 관용구에 익숙해지면 그것을 읽고 이해하는 것이 관용적 인 형태로 더 빠릅니다. – phonetagger

+0

나는 내 코드를 작성하는 동안 그것들을 받아 들인다. 나는 당신과 똑같이 쓸 것이지만 나는 언어에 접근하는 사용자들에게 그것들을 제안하지 않는다. – Jack

0

첫째 : 당신의 원하는 코드 isCapitalisVowel하지 기능 (확실히 아닌 함수 호출),하지만 해야한다 - 그들이 매개 변수를 통해 그것을받을 수있는 값을 확인할 수 있기 때문이다. ..

어쨌든 당신의 코드는 C++에서 가능하지 않습니다 ... 그러나 술어 + 효과의 순서로 시뮬레이트 될 수 있습니다. 술어는 매개 변수를 가져와 부울로 응답해야합니다. 술어가 true 인 경우 효과가 증가합니다. 다음 번에 나누기 및 폴백을 시뮬레이트하려면 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) 충분히 명백 ... 그리고 어쩌면, 진짜의 경우, (아마도 유지 보수) 더 나은 유연성을 :)