how to write a macro like this?

Discussion in 'C++' started by Peng Yu, Jun 26, 2008.

  1. Peng Yu

    Peng Yu Guest

    Hi,

    I want a macro #expand that can be expanded to one of the following
    depending on its argument

    f(i1)
    f(i1, i2)
    f(i1, i2, i3)

    ...


    For example,

    expand(1) would give me f(i1)

    expand(2) would give me f(i1, i2)

    expand(3) would give me f(i1, i2, i3)

    Is it possible to be done in macro? If it is possible, could you let
    me know how to do it?

    Thanks,
    Peng
    Peng Yu, Jun 26, 2008
    #1
    1. Advertising

  2. Peng Yu

    Stefan Ram Guest

    Peng Yu <> writes:
    >expand(1) would give me f(i1)
    >expand(2) would give me f(i1, i2)


    #include <iostream>
    #include <ostream>

    #define expand1 f(i1)
    #define expand2 f(i1, i2)

    #define expand(i) expand##i

    int f( int const i1, int const i2 ){ return 12; }
    int f( int const i1 ){ return 11; }

    int main()
    { int i1, i2;
    ::std::cout << expand(1) << "\n";
    ::std::cout << expand(2) << "\n"; }
    Stefan Ram, Jun 26, 2008
    #2
    1. Advertising

  3. Peng Yu

    Peng Yu Guest

    On Jun 25, 6:16 pm, Victor Bazarov <> wrote:
    > Peng Yu wrote:
    > > I want a macro #expand that can be expanded to one of the following
    > > depending on its argument

    >
    > > f(i1)
    > > f(i1, i2)
    > > f(i1, i2, i3)

    >
    > > ..

    >
    > > For example,

    >
    > > expand(1) would give me f(i1)

    >
    > > expand(2) would give me f(i1, i2)

    >
    > > expand(3) would give me f(i1, i2, i3)

    >
    > > Is it possible to be done in macro? If it is possible, could you let
    > > me know how to do it?

    >
    > //--------------------- here you go
    > #define with1args f(i1)
    > #define with2args f(i1,i2)
    > #define with3args f(i1,i2,i3)
    > #define formNname(i) with##i##args
    > #define expand(i) formNname(i)
    >
    > //---------------- test code
    > #include <iostream>
    > #include <ostream>
    >
    > void f(int) { std::cout << "f(int)\n"; }
    > void f(int,int) { std::cout << "f(int,int)\n"; }
    > void f(int,int,int) { std::cout << "f(int,int,int)\n"; }
    >
    > int main()
    > {
    > int i1=0, i2=0, i3=0;
    > expand(1);
    > expand(2);
    > expand(3);
    >
    > }
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    I think the example in my OP did not reflect the question that I
    wanted to ask.

    Suppose that the definitions of f(int), f(int, int) , f(int, int,
    int) ... in reality are very complex. However, the difference between
    them are minor, except the things that depend on different arguments.
    In this case, I would not want to write each definition individually.

    Also, in the code snippet that you showed, if the user needs f of 10
    arguments, I have to define it ahead of time. But since I can not
    enumerate all the possibilities, what if the user want an f of 100 or
    1000 arguments.

    I suspect that my request can not be done in macro. I looked up the
    code of boost tuple, which offers functions and classes of different
    number of arguments. It did not use macro in implementation in this
    aspect. I just want to double check if my inception is correct.

    Thanks,
    Peng
    Peng Yu, Jun 26, 2008
    #3
  4. Peng Yu

    Stefan Ram Guest

    Peng Yu <> writes:
    >Suppose that the definitions of f(int), f(int, int) , f(int, int,
    >int) ... in reality are very complex.


    It is usually recommended to refactor a complex function
    definition until it is not so complex anymore.

    >However, the difference between
    >them are minor, except the things that depend on different arguments.
    >In this case, I would not want to write each definition individually.


    One might use a single array or vector as an argument or
    write f as a a function with a variable number of arguments.
    Stefan Ram, Jun 26, 2008
    #4
  5. Peng Yu

    Peng Yu Guest

    On Jun 25, 7:45 pm, -berlin.de (Stefan Ram) wrote:
    > Peng Yu <> writes:
    > >Suppose that the definitions of f(int), f(int, int) , f(int, int,
    > >int) ... in reality are very complex.

    >
    > It is usually recommended to refactor a complex function
    > definition until it is not so complex anymore.
    >
    > >However, the difference between
    > >them are minor, except the things that depend on different arguments.
    > >In this case, I would not want to write each definition individually.

    >
    > One might use a single array or vector as an argument or
    > write f as a a function with a variable number of arguments.


    It might be OK to certain cases, but it is not suitable to the cases
    in my project.

    Thanks,
    Peng
    Peng Yu, Jun 26, 2008
    #5
  6. Peng Yu

    gpderetta Guest

    On Jun 26, 1:51 am, Peng Yu <> wrote:
    <snip>
    > I suspect that my request can not be done in macro. I looked up the
    > code of boost tuple, which offers functions and classes of different
    > number of arguments. It did not use macro in implementation in this
    > aspect. I just want to double check if my inception is correct.
    >


    Check the boost preprocessor library.

    --
    gpd
    gpderetta, Jun 26, 2008
    #6
  7. Peng Yu <> writes:

    > On Jun 25, 6:16 pm, Victor Bazarov <> wrote:
    >> Peng Yu wrote:
    >> > I want a macro #expand that can be expanded to one of the following
    >> > depending on its argument

    >>
    >> > f(i1)
    >> > f(i1, i2)
    >> > f(i1, i2, i3)

    >>
    >> > ..

    >>
    >> > For example,

    >>
    >> > expand(1) would give me f(i1)

    >>
    >> > expand(2) would give me f(i1, i2)

    >>
    >> > expand(3) would give me f(i1, i2, i3)

    >>
    >> > Is it possible to be done in macro? If it is possible, could you let
    >> > me know how to do it?

    >>
    >> //--------------------- here you go
    >> #define with1args f(i1)
    >> #define with2args f(i1,i2)
    >> #define with3args f(i1,i2,i3)
    >> #define formNname(i) with##i##args
    >> #define expand(i) formNname(i)
    >>
    >> //---------------- test code
    >> #include <iostream>
    >> #include <ostream>
    >>
    >> void f(int) { std::cout << "f(int)\n"; }
    >> void f(int,int) { std::cout << "f(int,int)\n"; }
    >> void f(int,int,int) { std::cout << "f(int,int,int)\n"; }
    >>
    >> int main()
    >> {
    >> int i1=0, i2=0, i3=0;
    >> expand(1);
    >> expand(2);
    >> expand(3);
    >>
    >> }
    >>
    >> V
    >> --
    >> Please remove capital 'A's when replying by e-mail
    >> I do not respond to top-posted replies, please don't ask

    >
    > I think the example in my OP did not reflect the question that I
    > wanted to ask.
    >
    > Suppose that the definitions of f(int), f(int, int) , f(int, int,
    > int) ... in reality are very complex. However, the difference between
    > them are minor, except the things that depend on different arguments.
    > In this case, I would not want to write each definition individually.
    >
    > Also, in the code snippet that you showed, if the user needs f of 10
    > arguments, I have to define it ahead of time. But since I can not
    > enumerate all the possibilities, what if the user want an f of 100 or
    > 1000 arguments.
    >
    > I suspect that my request can not be done in macro.


    It can be done, almost. You only need an additionnal cpp loop.

    http://www.ioccc.org/2001/herrmann1.hint
    http://www.ioccc.org/2001/herrmann1.c
    http://www.ioccc.org/2001/herrmann1.sh
    http://www.ioccc.org/2001/herrmann1.gcd
    http://www.ioccc.org/2001/herrmann1.times2


    > I looked up the
    > code of boost tuple, which offers functions and classes of different
    > number of arguments. It did not use macro in implementation in this
    > aspect. I just want to double check if my inception is correct.


    You could probably solve your problem with templates (and boost::mpl),
    but I don't think it would be any simplier than with C macros.



    What you are really longing for is merely lisp:

    (defmacro call-f-with-arguments (n)
    `(f ,@(loop :for i :from 1 :to n
    :collect (intern (format nil "I~A" i)))))

    (macroexpand '(call-f-with-arguments 7))
    --> (F I1 I2 I3 I4 I5 I6 I7)


    Or with local macros:

    (defun main ()
    (let ((i1 0) (i2 0) (i3 0))
    (macrolet ((call-f (n)
    `(f ,@(loop :for i :from 1 :to n
    :collect (intern (format nil "I~A" i))))))
    (call-f 3)))
    0)

    --
    __Pascal Bourguignon__
    Pascal J. Bourguignon, Jun 26, 2008
    #7
  8. Peng Yu

    tharinda_g

    Joined:
    Jun 23, 2008
    Messages:
    2
    Can you write a single function f() with a variable arguments list

    if you can write a function with a variable arguments then this can be handled differently. You can take variable arguments even for macros. use __VA_ARGS__
    tharinda_g, Jun 27, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dead RAM
    Replies:
    20
    Views:
    1,111
    John Harrison
    Jul 14, 2004
  2. D Senthil Kumar

    macro name from macro?

    D Senthil Kumar, Sep 20, 2003, in forum: C Programming
    Replies:
    1
    Views:
    578
    Jack Klein
    Sep 21, 2003
  3. sounak

    to get macro name from macro value

    sounak, Nov 22, 2005, in forum: C Programming
    Replies:
    17
    Views:
    501
    Mark McIntyre
    Nov 22, 2005
  4. Patrick Kowalzick
    Replies:
    5
    Views:
    470
    Patrick Kowalzick
    Mar 14, 2006
  5. Mike Manilone

    macro inside macro

    Mike Manilone, Oct 3, 2011, in forum: C Programming
    Replies:
    8
    Views:
    459
    Mike Manilone
    Oct 6, 2011
Loading...

Share This Page