Da eine Unze Erfahrung eine Menge Theorie wert ist, habe ich ein kleines Testprogramm ausprobiert für MULTILINE
:
#define MULTILINE(...) #__VA_ARGS__
const char *mstr[] =
{
MULTILINE(1, 2, 3), // "1, 2, 3"
MULTILINE(1,2,3), // "1,2,3"
MULTILINE(1 , 2 , 3), // "1 , 2 , 3"
MULTILINE( 1 , 2 , 3 ), // "1 , 2 , 3"
MULTILINE((1, 2, 3)), // "(1, 2, 3)"
MULTILINE(1
2
3), // "1 2 3"
MULTILINE(1\n2\n3\n), // "1\n2\n3\n"
MULTILINE(1\n
2\n
3\n), // "1\n 2\n 3\n"
MULTILINE(1, "2" \3) // "1, \"2\" \3"
};
Kompilieren Sie dieses Fragment mit, um es cpp -P -std=c++11 filename
zu reproduzieren.
Der Trick dahinter #__VA_ARGS__
ist, dass __VA_ARGS__
das Komma-Trennzeichen nicht verarbeitet wird. Sie können es also an den Stringing-Operator übergeben. Führende und nachfolgende Leerzeichen werden abgeschnitten, und Leerzeichen (einschließlich Zeilenumbrüche) zwischen Wörtern werden dann auf ein einzelnes Leerzeichen komprimiert. Klammern müssen ausgewogen sein. Ich denke, diese Mängel erklären, warum die Designer von C ++ 11 trotz #__VA_ARGS__
der Notwendigkeit roher String-Literale sahen.