2012-12-18 28 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標籤中的值需要是一個常量表達式。也就是說,你的直接問題的答案是:是的,你可以調用一個case標籤中的某些函數。但是,不是那些你試圖打電話的人。你可以有多個標籤是指一組語句,但:

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

我知道這並不能回答你的問題本身,而是你可以嘗試編碼它像這樣....

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

isXXX()函數的布爾返回類型將被提升爲一個int值,並將其作爲0(false)或1(true)添加到計數中。

+3

這有效,但爲了便於閱讀,我會說使用函數的結果作爲布爾數據類型,所以'capitalCount + = isCapital(x)? 1:0' – Jack

+2

@傑克 - 這是「成語」的東西之一。隨處可見的代碼充滿了它們。你可以擁抱常見的習語並編寫簡潔的代碼,或者你可以避開常見的習語,寫出一些認爲更可讀的代碼,但其他人認爲是混亂的代碼。如果你習慣了這個成語,閱讀它並理解它的慣用形式會更快。 – phonetagger

+0

當我編寫自己的代碼時,我擁抱他們,我會按照自己的方式編寫代碼,但我不會向接近該語言的用戶推薦他們。 – Jack

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沒那麼簡單,但(恕我直言)明顯不夠......也許,在一些真實的案例,具有更好的靈活性(也許可維護性):)