dimanche 29 mars 2015

How can I use C-style macros with C++11-style constructor calls?

I've found what seems to be an incompatibility between using C-style macros and using the new unified list-initialization form introduced in C++11, but it seems incredible that this sort of thing would be absolutely impossible to write, so I assume I'm missing something.


Here's the issue: curly brackets seem to be ignored when the preprocessor looks to find a macros arguments. A call like MACR(Range{2,4}) is misinterpreted as having two arguments, Range{2 and 4. In the following code, it's all good (well, poor style, but it works) until the marked line:



#include <iostream>
using namespace std;

struct Range { int st, fn; };
ostream& operator << (ostream& out, const Range& r)
{ return out << "(" << r.st << "," << r.fn << ")"; }

#define COUT(X) (cout << (X) << endl)

int main()
{
COUT(3);
Range r {3,5};
COUT(r);

COUT(Range{3,5}); //this line won't compile
}


It gives the following error message:



badmacro.cpp:16:18: error: macro "COUT" passed 2 arguments, but takes just 1
COUT(Range{3,5});
^
compilation terminated due to -Wfatal-errors.


Especially when working with older libraries, it's sometimes unavoidable to use macro calls; surely we're not supposed to forgo the new syntax in those cases? Is there an official workaround for this?


Aucun commentaire:

Enregistrer un commentaire