Topic: C++ pre-processor defect(?) when passed template params


Author: Gianni Mariani <gi2nospam@mariani.ws>
Date: Sun, 26 Feb 2006 16:18:56 CST
Raw View
The use of templates is becoming more and more common.  Macros, while an
anathema, are still of great benefit in many instances because of the
unfortunate verboseness of many template expressions which can't be
simplified (even if we had template typedefs).

Quite simply, the comma (",") used in template arguments (like "<a,b>")
is not interpreted as if it is a template argument. (note the line
marked as "error" below.)

The code below is a simple example of the problem. In practice, this
issue has bitten me numerous times causing me to need to write even more
verbose code.

template <typename A, typename B>
struct X;

void Y( int, int );

#define macro( A )  A

int main()
{
     macro( Y(1,2) ); // ok
     macro( X<int,int> ) *x; // error
}

Implementing this feature is somewhat difficult because it's difficult
to interpret if these are less-than/greater-than or template parameters.

i.e.

macro( a < b ) // malformed template ?

One way to solve this would be to merge the pre-processor with the
lexical analysis so that the pre-process phase does have knowledge of
the parser's context at that point.  I can imagine that there would be a
whole set of issues regarding template instantiation and typename
deduction that would likely make this impractical.

Another idea would be to "inform" the pre-processor ...

e.g.
#definet macro<A> A
macro< X<int,int> > *x

OK, I don't like that one either.

Perhaps a special digraph...

macro( X[<int,int>] ) *x;

I could live with that.

Ideas ?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Richard Smith" <richard@ex-parrot.com>
Date: Mon, 27 Feb 2006 19:56:37 CST
Raw View
Gianni Mariani wrote:
>
> template <typename A, typename B>
> struct X;
>
> void Y( int, int );
>
> #define macro( A )  A
>
> int main()
> {
>      macro( Y(1,2) ); // ok
>      macro( X<int,int> ) *x; // error
> }

One solution is to use a helper template to massage the type into a
form that the preprocessor will can cope with, and then wrap this up in
a macro:

  template <class T> struct fn_argument {};
  template <class T> struct fn_argument< void(T) > {
    typedef T type;
  };

#define MACRO_IMPL(x) x // or whatever the implementation is
#define MACRO(arglist) MACRO_IMPL( fn_argument< void arglist >::type )

  MACRO(( X<int, int> ));  // Note two sets of brackets.

A problem with this is that two versions of MACRO are needed -- the one
given, and one with a 'typename' for use when the macro arguments are
dependent on a template parameter.

--
Richard Smith

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]