2017-03-29 26 views
-2

In unserem letzten Projekt schreibe ich ein Makro, das unter bestimmten Bedingungen und wie hier erklärt C multi-line macro: do/while(0) vs scope block Ich habe versucht, do - while, um das zu erreichen. Unten finden Sie Beispielcode zu veranschaulichen, dass:Wie schreibe ich Multiline-Makro mit Continue- oder Break-Ausdruck

#define PRINT_ERROR_AND_CONTINUE_IF_EMPTY(dummy,dummystream,symbol,errorString) \ 
    do{ \ 
    if(dummy.empty())\ 
    {\ 
     dummyStream<<symbol<<",Failed,"<<errorString<<std::endl;\ 
     continue;\ 
    }\ 
    }while(0) 
int main() 
{ 
    int x =9;  
    std::ofstream& ofsReportFile; 
    while(x>5) 
    { 
     std::string str; 
     PRINT_ERROR_AND_CONTINUE_IF_EMPTY(str,ofsReportFile,"Test","Test String is Empty"); 
     std::cout<<x<<std::endl; 
     x--; 
    } 
    return 0; 
} 

Dies ist jedoch nicht wie erwartet funktioniert, und die Grund-Anweisung innerhalb sie weiterhin werden kann, während so die Frage, wie mehrzeiligen Makro zu schreiben, mit Aussage fortsetzen und auch Benutzer, dass Makro kann es wie CONTINUE_IF_EMPTY (str) ;

+7

Kann ich nur sagen "bitte nicht". –

+3

Entfernen Sie das 'do ... while'. Noch besser, entfernen Sie das gesamte Makro. –

+0

Ich muss an mehreren Orten in Long for Schleife überprüfen, wenn etwas leer ist, dann Fehler drucken und weiter so sollte ich diesen Code überall wiederholen – Kapil

Antwort

1

Wie wäre es mit einem Lambda? Dies scheint ein guter Ersatz für das Makro zu sein, das sowohl global (wie alle Makros) als auch seltsam spezifisch ist. Außerdem erhalten Sie Aufnahmen, um die wiederholten Parameter zu reduzieren.

int main() 
{ 
    int x = 9; 
    std::ofstream& ofsReportFile = /* ... */; 

    auto const reportEmpty = [&](std::string const &str) { 
     if(str.empty()) { 
      ofsReportFile << "Test, Failed, Test String is Empty" << std::endl; 
      return true; 
     } 
     return false; 
    }; 

    while(x > 5) 
    { 
     std::string str; 

     if(reportEmpty(str)) 
      continue; 

     std::cout << x << std::endl; 
     x--; 
    } 
} 
+0

Gibt es einen Grund, keine Funktion anstelle eines Lambda zu verwenden? Ich sage nicht, dass es falsch ist, es ist nur meine Erfahrung, dass ein Lambda mehr Denkprozess erfordert als eine normale Funktion (weil ich zum Beispiel die lokale Funktion für den 'reportEmpty' Namen anstatt über Funktionen usw. scannen muss). Ein Lambda ist für mich eher etwas, das Sie verwenden, wenn Sie den Aufrufer brauchen, um dem Angerufenen mitzuteilen, welche Art von Logik zu verwenden ist (zum Beispiel wenn Sie für eine bestimmte Eigenschaft eines Objekts Find verwenden). Dies wäre für mich in Ordnung, um zu einer Funktion statt zu einem Lambda umzuformen. – Default

+1

@Default Ich nutze die Capture-Liste, um zu vermeiden, dass bei jedem Aufruf der Ausgabestrom übergeben wird. Abgesehen davon, hast du recht, dass es in eine Funktion extrahiert werden könnte - aber wir wissen nicht, ob diese Funktionalität woanders verwendet wird. Wenn dies der Fall ist, ist die beste Lösung eine Funktion höherer Ordnung: 'auto makeEmptyReporter (std :: ofstream & s) {return [& s] (std :: string const & str) {/ * ... * /}; } ' – Quentin