>From: "Paul Mensonides" <[EMAIL PROTECTED]> > Terje Slettebų wrote: > > Is there some way (using PP-lib, or whatever), to pass a template-id > > with more than one parameter (thus, it contains at least one comma), > > to a macro? > > > > E.g.: > > > > #define TEST(a) test<a> t; > > > > TEST(std::pair<char,int>) // Won't work > > > > Maybe some sort of variation of BOOST_PP_IDENTITY: > > > > #define BOOST_PP_IDENTITY1(a) a > > #define BOOST_PP_IDENTITY2(a,b) a,b > > #define BOOST_PP_IDENTITY3(a,b,c) a,b,c > > > > etc. > > > > TEST(BOOST_PP_IDENTITY2(std::pair<char,int>)) // Now ok > > I'll answer all three of these emails at once, since they are about the same > thing. First, the above will cause problems, specifically problems like this: > > #define T1(a) T2(a) > #define T2(a) test<a> t; > > #define IDENTITY2(a, b) a, b > > T1(IDENTITY2(std::pair<char, int>)) // error > > I.e. by the time that T2 is invoked, IDENTITY2 has already expanded, which > yields too many arguments to T2.
Right. However, for simple use (only one level of macro expansion), this works, and has the advantage of being simple and non-intrusive to use. > What we need is a general solution and a set > of conventions for passing types. This is difficult without variadics to do > with the preprocessor itself. Specifically, you have to use the core language: > > template<class T> struct wrap { > typedef T type; > }; > > template<class T> struct wrap<void (T)> { > typedef T type; > }; > > #define TYPE(x) wrap<void x>::type > > TYPE((int)) // okay > TYPE((std::pair<char, int>)) // okay > > However, this has its own problems. Specifically, it is using function types to > store the type--which is inside parentheses and therefore protected from the > preprocessor. The use of function types with cause certain things to error: > > TYPE(( void )) // error > TYPE(( int (int, int) )) // function type altered to pointer-to-function > TYPE(( int[2] )) // array altered to pointer Right. It's similar to Aleksey's "round lambda". > There is only one other language construct that might be of use here: > pointers-to-members. Specifically, it is parenthesized, yet does not undergo > promotion/alteration when used in a parameter list. However, it is intrusive: > > template<class> struct wrap; > template<class T> struct wrap<void (T::*)(void)> { > typedef T type; > }; > > #define TYPE(x) wrap<void T(void)>::type > > TYPE(( std::pair<int, int>::* )) > ^^^ > Also, this cannot be used for non-class types--which can still have commas in > them: > > template<class T, class U> struct typelist { > typedef T head; > typedef U tail; > }; > > TYPE(( typelist<int, nil>::head::* )) // error > > So, without variadic macros, there is no "good" solution. Instead, you have to > resort to hacks that require you to know the number of unbound commas in the > type: > > #define IN(s, x) (s) x > #define OUT(x) BOOST_PP_TUPLE_REM x > > #define M1(type) M2(type) > #define M2(type) OUT(type) > > MACRO( IN(2, (std::pair<int, int>)) ) I'm not sure how this latter solution could be used. How could MACRO retrieve the type being passed? Thanks. :) Regards, Terje _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost