2016-07-31 4 views
0

Ich möchte eine C++ Makro-Funktion zu debuggen erstellen, und ich möchte es, wie dies funktioniert:Eine Zeile Debug-Makro

int main(){ 
    int a = 3, b = 5, c = 7; 
    string s = "<"; 

    print(a,s,b); 
    print(a,s,b,s,c); 
} 

OUTPUT: 
3 < 5 
3 < 5 < 7 

ich viel über variadische Makros gelesen habe, aber alles, was ich versucht zu programmieren, würde überhaupt nicht funktionieren.

Ich dachte über die Verwendung von Lambda, aber nicht mit Algorithmus, um es zu tun.

Ich brauche es wie ein Code-Zeile, cos es nur für das Debuggen ist und mehr als dass ich eine komplexere Funktion schaffen könnte, aber ich denke, das muss möglich sein ...

+0

Ein Makro kann keinen Laufzeittyp wie 'std :: string' enthalten. Lambdas sind auch eine Laufzeitsache. Makros dienen zur Vorverarbeitung, lassen vor jeder Kompilierung die Laufzeit frei. – Downvoter

+0

was ist mit char *? oder Wörter, die keine Zeichenkette sind, zum Beispiel print (abc), wo abc wie #abc behandelt werden kann. – Daniel

+0

Wenn 'abc' wie' # abc' behandelt werden kann, dann ist es etwas vom Präprozessor. 'char *' kann das auch nicht machen. Auf "int" kann auch vom Preprozessor nicht zugegriffen werden. Sie könnten ein Analyseprogramm schreiben, um die Werte von Variablen zu einem bestimmten Zeitpunkt während der Ausführung des Programms herauszufinden, oder einfach einen Debugger oder etwas verwenden, das zur Laufzeit funktioniert. Der C-Präprozessor hat seine Grenzen. [m4] (http://www.gnu.org/software/m4/m4.html) ist eine nette Alternative, die hier nützlich sein könnte. – Downvoter

Antwort

1

Wenn Sie einverstanden sind die ersetzen Separator mit ‚<<‘ (statt ‚,‘), dann ist das Makro sehr einfach zu definieren (Anmerkung jedoch, dass print kein guter Name für einen Makro ist, das ist, warum ich es entsprechend umbenannt):

#include <iostream> 
#include <string> 

#ifdef DEBUG 
#define DEBUG_PRINT(x) std::cout << x << std::endl 
#else 
#define DEBUG_PRINT(x) 
#endif 

int main(){ 
    int a = 3, b = 5, c = 7; 
    std::string s = "<"; 

    std::cout << "START" << std::endl; 

    DEBUG_PRINT(a << s << b); 
    DEBUG_PRINT(a << s << b << s << c); 

    std::cout << "END" << std::endl; 
    return 0; 
} 

Ausgang :

$ g++ -DDEBUG main.cpp && ./a.out 
START 
3<5 
3<5<7 
END 

$ g++ main.cpp && ./a.out 
START 
END 
2

können Sie variadische Vorlage statt MACRO verwenden:

template <typename ... Ts> 
void print(Ts&&... args) 
{ 
    int dummy[] = {0, ((std::cout << args), 0)...}; 
    static_cast<void>(dummy); // avoid warning for unused variable 
    std::cout << std::endl; 
} 

oder in C++ 17

template <typename ... Ts> 
void print(Ts&&... args) 
{ 
    (std::cout << ... << args) << std::endl; 
} 
1

ich fast erreicht, was ich (mit 2 Zeilen Code) wollte:

#define print(args...) {db,args; cerr<<endl;} 
struct dbg{template<typename T> dbg& operator , (const T& v){cerr<<v<<" "; return *this; }} db; 

jetzt kann ich nur drucken (1,2, "asjd") und es funktioniert gut

+0

Sie können sogar die Struktur innerhalb des Blocks seit C++ 11 deklarieren und definieren (und so die globale entfernen). – Jarod42

+0

Sie meinen ich kann die Struktur innerhalb de Makros deklarieren? Wie? – Daniel

+0

In der Tat können Sie lokale Struktur innerhalb Funktion, aber NICHT ** Vorlage ** Methode deklarieren, so dass ich falsch lag. : / – Jarod42