Bedingte Ausgabe



  • Ich möchte im Consolen Modus Daten zur Kontrolle ausgeben. Bisher verunstalte ich meine Codes mit unzähligen #ifdefs.

    std::wstring path(InitPath());
        int id = InitID();
    #ifdef _CONSOLE
        std::wcout << path << L" " << id << std::endl;
    #endif  // _CONSOLE
    

    Gibts eine elegante Möglichkeit das zu umgehen? Zum Beispiel einen

    std::wostream& trace(std::wcout);
    

    definieren, den ich zentral via

    #ifdef _CONSOLE
        std::wostream& trace(std::wcout);
    #else
        std::wostream& trace(/* NIRVANA */);
    #endif  // _CONSOLE
    

    umlenken kann. Werden keine Ausgaben benötigt, dann wird's ins Nirvana gestreamt. Also keine Ausgaben auch nicht in ein physikalisches File.

    trace << path << L" " << id << std::endl;
    

    Danke für eure Hilfe!


  • Mod

    /dev/null?

    edit: Oder wenn du es streng plattformunabhängig haben willst: Einfach einen fstream ohne eine Datei zu öffnen.



  • SeppJ schrieb:

    /dev/null?

    Was meinst du?


  • Mod

    Tomahawk schrieb:

    SeppJ schrieb:

    /dev/null?

    Was meinst du?

    Dateistream mit /dev/null als Ausgabedatei.



  • #include <fstream>
    #include <iostream>
    
    #ifdef _DEBUG
    std::wostream& trace(std::wcout);
    #else
    std::wofstream trace;
    #endif
    
    int main() {
      trace << L"Hello world!" << std::endl;
      return 0;
    }
    


  • Dein Problem ist dadurch nur zur Hälfte gelöst. Die Funktionsaufrufe werden trotzdem ausgeführt (was durchaus auf die Performance geht), und dass der Compiler das wegoptimiert bezweifle ich zurecht.

    Wäre ein Makro nicht schöner?

    #ifdef _CONSOLE
        #define dump(...) dump(_VA_ARGS_)
    #else
        #define dump(...)
    #endif
    

    Und dump ist dann eine variadic function (eher unschön) oder eine Funktion mit variadic templates (C++11).

    Das wäre so mein Ansatz. 😋

    Edit: Oder es geht dir gar nicht um Performance. In diesem Fall ist natürlich Sepps Lösung besser.

    Edit²: Vorschlag für den nächsten Standard: Ein neues Makro-Level, ein Präprozessor Nr.2 der vor dem ersten ausgeführt wird. Vor dem Befehl kommen Zwei Rauten.
    Damit auch sowas möglich ist:

    ##define bla #ifdef ...
    

    🤡 🤡 😃



  • Sone schrieb:

    Dein Problem ist dadurch nur zur Hälfte gelöst. Die Funktionsaufrufe werden trotzdem ausgeführt (was durchaus auf die Performance geht), und dass der Compiler das wegoptimiert bezweifle ich zurecht.

    Wäre ein Makro nicht schöner?

    #ifdef _CONSOLE
        #define dump(...) dump(_VA_ARGS_)
    #else
        #define dump(...)
    #endif
    

    Und dump ist dann eine variadic function (eher unschön) oder eine Funktion mit variadic templates (C++11).

    Das wäre so mein Ansatz. 😋

    Edit: Oder es geht dir gar nicht um Performance. In diesem Fall ist natürlich Sepps Lösung besser.

    Edit²: Vorschlag für den nächsten Standard: Ein neues Makro-Level, ein Präprozessor Nr.2 der vor dem ersten ausgeführt wird. Vor dem Befehl kommen Zwei Rauten.
    Damit auch sowas möglich ist:

    ##define bla #ifdef ...
    

    🤡 🤡 😃

    Klar mit einem #define!

    #ifdef _CONSOLE
    #define CONSOLE_EXPRESSION(x) x
    #else
    #define CONSOLE_EXPRESSION(x)
    #endif  // _CONSOLE
    
    int main() {
      CONSOLE_EXPRESSION(std::wcout << L"Hello World!" << std::endl);
      return 0;
    }
    


  • Gab es da nicht eine Regel dass man auf define in C++ verzichten sollte, wenn es denn irgendwie geht?



  • Grasshopper schrieb:

    Gab es da nicht eine Regel dass man auf define in C++ verzichten sollte, wenn es denn irgendwie geht?

    Nö, wieso denn das? Man sollte nur Konstanten und Enumerationen und Inline Funktionen benutzen, statt den entsprechenden Makro-Varianten. Also die Sprachfeatures mehr ausnutzen. Hier ist aber ein Makro definitiv angebracht.

    Tomahawk schrieb:

    Sone schrieb:

    Dein Problem ist dadurch nur zur Hälfte gelöst. Die Funktionsaufrufe werden trotzdem ausgeführt (was durchaus auf die Performance geht), und dass der Compiler das wegoptimiert bezweifle ich zurecht.

    Wäre ein Makro nicht schöner?

    #ifdef _CONSOLE
        #define dump(...) dump(_VA_ARGS_)
    #else
        #define dump(...)
    #endif
    

    Und dump ist dann eine variadic function (eher unschön) oder eine Funktion mit variadic templates (C++11).

    Das wäre so mein Ansatz. 😋

    Edit: Oder es geht dir gar nicht um Performance. In diesem Fall ist natürlich Sepps Lösung besser.

    Edit²: Vorschlag für den nächsten Standard: Ein neues Makro-Level, ein Präprozessor Nr.2 der vor dem ersten ausgeführt wird. Vor dem Befehl kommen Zwei Rauten.
    Damit auch sowas möglich ist:

    ##define bla #ifdef ...
    

    🤡 🤡 😃

    Klar mit einem #define!

    #ifdef _CONSOLE
    #define CONSOLE_EXPRESSION(x) x
    #else
    #define CONSOLE_EXPRESSION(x)
    #endif  // _CONSOLE
    
    int main() {
      CONSOLE_EXPRESSION(std::wcout << L"Hello World!" << std::endl);
      return 0;
    }
    

    👍
    Jup, damit wäre es dann gelöst.


Anmelden zum Antworten