MACROS overload

Pages: 12
hi all
1
2
3
4
5
6
7
8
9
#define S(...) printf("%s %s","AT","OK")
#S S1
#define S1(x) printf("%s %s",(x),"OK")  
#S1 S2
#define S2(x,y) printf("%s %s",(x),(y))
 
S();  //print AT OK
S("TT");  //print TT OK
S("TT","KK"); //print TT KK 

how to make MACROS overload
in the following mode that I can use
S();
S("arg1");
S("arg1","arg2");

and print will be
for first call
AT OK
2nd call
TT OK
3rd
TT KK
Last edited on
how to make something like this ?


What does "like this" mean?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

void myPrint()
{
   cout << "NOTHING HERE" << '\n';
}

template<typename T> void myPrint( T only )
{
   cout << only << '\n';
}

template<typename T, typename... Args> void myPrint( T first, Args... rest )
{
   cout << first << ' ';
   myPrint( rest... );
}

int main()
{
   myPrint();
   myPrint( 0 );
   myPrint( 1, "No" );
   myPrint( 2, 3, 4, "OK", 6, 7, 8 );
}


NOTHING HERE
0
1 No
2 3 4 OK 6 7 8
Last edited on
sorry , Im edited 1st post

I want to make call for S with 0,1,2 arguments
alexblade wrote:
I want to make call for S with 0,1,2 arguments

I've edited my post to include the 0-argument case.

They are functions, not macros ... not that I think that's a problem.
you cannot directly overload macros.
you can make one macro that takes an additional parameter to choose what code to run.
you can make 3 overloaded normal or template functions. If you need to force them inline, and the compiler refuses, you can do that.

here, pass in 2 strings. if both are length zero / empty, do s(), if first has data and second does not, do s(tt) else do s(ttkk)
given that you are passing empty strings or not, there is very likely a way to arrange this such that you don't need the if statements, and just print the strings passed into it, if the conditional cost bothers you.

you can fake overloading with more macros, but its complicated and extremely ugly. see : https://stackoverflow.com/questions/5172435/overload-c-c-preprocessor-macro-on-structure-of-its-argument
Last edited on
They are functions, not macros ... not that I think that's a problem.


Not just not a problem, but an enormous improvement.
thank you but this is not as I want
1
2
3
S();  //print AT OK
S("TT");  //print TT OK
S("TT","KK"); //print TT KK  


if S() should be print "AT", "OK"
if S("TT") should be print , first arg from S should replace template from macros so result, print "TT", "OK" // here OK because in the S only one arg
if S("TT","KK") then first arg should replace first default from macros and second the same and result print "TT", "KK" because S have two arguments

and very desired via macros
I can do this with 1,2 argument and nice not as in your link at stackoverflow with CONCAT but problem when 0 arg

w/o 0 arg we can do like this
#define S1(x, y, ...) printf("%s %s",(x),(y))
#define S(...) S1(__VA_ARGS__, "OK", "")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>

using namespace std;

void S(string first = "AT", string second = "OK")
{
    cout << first << " " << second << '\n';
}

int main()
{
  S();  //print AT OK
  S("TT");  //print TT OK
  S("TT","KK"); //print TT KK 
}
Last edited on
yes thank you
as function with default argument value its one method. I know about this.

but I need the same but with macros , sure, if basically it possible
We need to understand what problem you're trying to solve. The problem you SAID you have has been solved, but you're saying it's not enough.

So what is the actual problem?
Sorry for misunderstanding

the actual problem to do this with macros not with function
But what's the problem? Why do you need to do it with a macro when we're shown you how to do it with a proper function? There must be some reason you have to do it with a macro instead of using a better option.
the actual problem to do this with macros not with function

It can't be done. Macros cannot be overloaded and the (...) mechanism cannot do what you want.
and the convoluted multi-macro thing I linked did not do it for you either? What happened when you tried it?
Wow. I missed that monster macro thing. Maybe it's kind of possible, but I can't comprehend that macro mess. The following code seems bizarre since there's no complaint about x and y being undefined. They are macroed away before the compiler sees them, but it looks strange. And that's just the start of the weirdness.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

#define CONCAT_( x, y ) x ## y
#define CONCAT( x, y ) CONCAT_( x, y )
#define IS_SINGLE_1(...) 0
#define IGNORE(...)
#define IS_SINGLE_2_0           0 IGNORE(
#define IS_SINGLE_2_IS_SINGLE_1 1 IGNORE(
#define IS_SINGLE( x ) CONCAT( IS_SINGLE_2_, IS_SINGLE_1 x ) )

int main() {
    std::cout << IS_SINGLE((x, y)) << '\n';  // 0
    std::cout << IS_SINGLE(x)      << '\n';  // 1
}
Last edited on
I guess I figured out the monster macro. The biggest thing I learned is that this is legal:

1
2
#define F( x )
int main() { F( a b c d ); }

So you are allowed to pass multiple space-separated tokens as one argument.

1
2
3
4
5
6
7
8
#include <iostream>

#define F( x ) std::cout << #x << '\n';

int main() {
    F( one  two  three   four  five ); // prints "one two three four five\n"
                                       // note that the spaces are normalized
}

Keep in mind that this is the preprocessor, not the language. The strangeness comes from the preprocessor screwing around with the text before the compiler sees it.

Anyway, that hint and noting the extra closing paren at the end of IS_SINGLE(x) (and how the IGNORE( calls will eat it and any tokens that need to disappear) pretty much explains the mechanism.
Same, I had not seen this before this question and did a search on what was possible. Its clever, in a 'now we have to fire you for doing that' kind of way. I wonder if anyone else in the class got this one...
Last edited on
Hi guys

I dont like this method with CONCAT... to many rows for such small task

so at the moment I did it with 4 lines
1
2
3
4
5
6
7
#define GET_MACRO(_1,_2, NAME,...) NAME
#define FOO(...) GET_MACRO(__VA_ARGS__, FOO2, FOO1)(__VA_ARGS__)
#define FOO1(x) ABC(F(x))
#define FOO2(x,y) ABC(F(x), F(y))

FOO(World);         
FOO(foo,bar);



so now I have two questions

1) is it possible to make with less then 4 rows macros overload?

2) how to overload for 0 arg in this mode
FOO() -> ABC()
Last edited on
Heh, Sorry I’m late to this discussion.

It is easily possible. It is messy, though.

Here’s an example in C89:
http://www.cplusplus.com/forum/lounge/108294/


That said, both C99 and C++ allow default arguments — I find it very unlikely that you haven’t got an XY problem.
Pages: 12