There are some cases where you need to (a) have a macro which (b) parenthesizes one of its arguments in (c) a case where the language does not allow parentheses.
Simple example:
#define MAKE_STRUCT(name, base) struct name : base { }
struct X { };
MAKE_STRUCT(Y, X); // ok
MAKE_STRUCT(Z, (X)); // error
This is an error because we're expecting a type name and we get (
. ecatmur provides a clever workaround for this by taking advantage of the fact that there are other parts of the language that do allow for an extra set of parentheses:
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define MAKE_STRUCT(name, base) struct name : argument_type<void(base)>::type { }
struct X { };
MAKE_STRUCT(Y, X); // ok
MAKE_STRUCT(Z, (X)); // ok
This compiles on gcc and clang, but it does not compile on MSVC. Is there either an MSVC-specific trick to allow for parentheses or a different trick that works on all three compilers?
This possibly-parenthesized type is passed through several macros - so I'm not sure that the other answers could apply (the context here is trying to pass multiple template parameters to a fixture using Catch2's TEST_CASE_METHOD()
).