>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

Reply via email to