how to write a macro like this?

P

Peng Yu

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
 
S

Stefan Ram

Peng Yu said:
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"; }
 
P

Peng Yu

//--------------------- 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

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
 
S

Stefan Ram

Peng Yu said:
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.
 
P

Peng Yu

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


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
 
G

gpderetta

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.
 
P

Pascal J. Bourguignon

Peng Yu said:
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)
 
Joined
Jun 23, 2008
Messages
2
Reaction score
0
Can you write a single function f() with a variable arguments list

Peng Yu said:
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

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__
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top