2014-01-18 2 views
0

Я предполагаю, что это более гипотетично, чем практично, но мне было интересно, можно ли использовать оператор switch, который возвращает «true» или «false» внутри «assert». Я понимаю, что есть лучшие способы сделать это, но я хочу взглянуть на эту проблему с точки зрения обработки ошибок, а не на дезинфекцию ввода пользователя.Используйте оператор switch внутри «assert» (C++)

Например, рассмотрим класс Date, который принимает ввод, задающий дату. В функции члена SetDate() класса я хотел бы поставить «assert», который обрабатывал бы ошибки, вызванные входными данными, такими как «13» за месяц, или 30 дней в месяц «2» (февраль). Было бы тривиально, чтобы написать заявление переключатель, который делает это:

switch(nMonth){ 
    case 1: 
    case 3:(etc) 
     if(nDay>=1 && nDay <=31) 
      return true; 
     else 
      return false; 
     (etc) 
     default: 
      return false; 
     } 

Предполагая, что оператор коммутатора работает по желанию, что мне нужно сделать, чтобы заставить его работать в схеме обработки ошибок «утверждать»? Я пробовал это как есть, но (неудивительно) это не скомпилировалось.

Редактировать: @Yu Hao: Вот как я его исправил. Я использовал функцию bool.

bool TestDate(int nMonth, int nDay, int nYear){ 
     switch(nMonth){ 
       case 1: 
       case 3: 
       case 5: 
       case 7: 
       case 8: 
       case 10: 
       case 12: 
        if(nDay >=1 && nDay <=31) 
         return true; 
        break; 
       case 4: 
       case 6: 
       case 9: 
       case 11: 
        if(nDay >=1 && nDay <=30) 
         return true; 
        break; 
       case 2: 
        if((nYear % 400 == 0) || ((nYear % 100 !=0) &&(nYear % 4 == 0))){ 
         if(nDay >=1 && nDay <=29) 
          return true;} 
        else if(nDay >=1 && nDay <=28) 
         return true; 
        else 
         return false; 
        break; 
       default: 
        return false; 

     } 
     return 0; 
    } 
    Date(int nMonth = 1, int nDay = 1, int nYear = 1970){ 
     assert(TestDate(nMonth,nDay,nYear)); 
     m_nMonth = nMonth; 
     m_nDay = nDay; 
     m_nYear = nYear; 
    } 
+0

Вы * можете * положить его в лямбда, но я вижу небольшую точку. – chris

+0

Этот оператор 'switch' в' TestDate() 'довольно уродливый - все случаи проваливаются, если тесты не выполняются, но это происходит, потому что, если какой-либо из ранних тестов терпит неудачу, последующие будут терпеть неудачу , Возможно, это было спроектировано именно так, но похоже, что это была счастливая случайность. –

+0

@Michael: Я помещал инструкции «break» в соответствующие места, но gcc-компилятор дал предупреждение: «Control доходит до конца не-void-функции». Я не получил предупреждения, когда инструкции «break» были опущены. – Huaidan

ответ

2

switch заявление не имеет значения возврата, то такие заявления return false или в switch заявлении относится к функции, что они находятся. Таким образом, вы не можете использовать switch внутри assert, но вы можете поставить функция это switch заявление внутри assert.

0

Вы не можете использовать switch внутри assert. assert принимает выражение. switch - это утверждение, а не выражение.

Что вы можете сделать, это использовать оператор trinary. Это будет не очень хорошо, если ваш оператор switch большой.

assert (((nMonth==1) || (nMonth == 3) || (nMonth == 5) || …) ? 
     ((nDay >= 1) && (nDay <= 31) : 
     (nMonth==2) ? ((nDay >= 1) && (nDay <= 28) : 
     …); 
Смежные вопросы