By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,366 Members | 1,364 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,366 IT Pros & Developers. It's quick & easy.

MACRO and template with two ( or more ) parameters

P: n/a
Hi

if have simple macro defined this way:
#define M_OPplus( classname ) typedef classname operator+(const
classname& rhs);

and a template class :
template<typename X, typename Y>
class Test1
{
public:
double run();
M_OPplus( Test1<X,Y)
};
The compiler (VS2003) is complaining : warning C4002: too many actual
parameters for macro, . I think it is related to the comma in the
middle , the preprocessor may think that i am passing two parameters
to the macro.

Is it possible to fix it and does it conform with the C++ standart?

Many Thx

Sep 14 '07 #1
Share this Question
Share on Google+
12 Replies


P: n/a
sw*****@googlemail.com wrote:
Hi

if have simple macro defined this way:
#define M_OPplus( classname ) typedef classname operator+(const
classname& rhs);

and a template class :
template<typename X, typename Y>
class Test1
{
public:
double run();
M_OPplus( Test1<X,Y)
^

the comma split up your argument into to parts

write
M_OPplus(( Test1<X,Y))

};
The compiler (VS2003) is complaining : warning C4002: too many actual
parameters for macro, . I think it is related to the comma in the
middle , the preprocessor may think that i am passing two parameters
to the macro.

Is it possible to fix it and does it conform with the C++ standart?

Many Thx

--
Thanks
Barry
Sep 14 '07 #2

P: n/a
<sw*****@googlemail.comwrote in message
news:11**********************@y42g2000hsy.googlegr oups.com...
if have simple macro defined this way:
#define M_OPplus( classname ) typedef classname operator+(const
classname& rhs);

and a template class :
template<typename X, typename Y>
class Test1
{
public:
double run();
M_OPplus( Test1<X,Y)
};
The compiler (VS2003) is complaining : warning C4002: too many actual
parameters for macro, . I think it is related to the comma in the
middle , the preprocessor may think that i am passing two parameters
to the macro.
Your correct.

Is it possible to fix it and does it conform with the C++ standart?
Yes. You can use a little trick that involves passing a name of a macro
function to the M_OPplus macro which calls it to get at the tokens.
Something like this:
#define M_OPplus(classname_macro) \
typedef classname_macro() \
operator+(const classname_macro()& rhs)
template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};
See what I am getting at here?

Sep 14 '07 #3

P: n/a
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
sw*****@googlemail.com wrote:
[...]
the comma split up your argument into to parts

write
M_OPplus(( Test1<X,Y))
[...]

That introduces extra parenthesis which can muck up syntax. For instance:
This has a syntax error:
_______________
#define M_OPplus(classname) \
typedef classname \
operator+(const classname &rhs)

template<typename X, typename Y>
class Test1 {
public:
double run();
M_OPplus((Test1<X,Y>));
};
_______________

This does not:
_______________
#define M_OPplus(classname_macro) \
typedef classname_macro() \
operator+(const classname_macro()& rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};
_______________

Sep 14 '07 #4

P: n/a
Chris Thomasson wrote:
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
>sw*****@googlemail.com wrote:
[...]
>the comma split up your argument into to parts

write
M_OPplus(( Test1<X,Y))

[...]

That introduces extra parenthesis which can muck up syntax. For instance:
This has a syntax error:
_______________
#define M_OPplus(classname) \
typedef classname \
operator+(const classname &rhs)

template<typename X, typename Y>
class Test1 {
public:
double run();
M_OPplus((Test1<X,Y>));
};
_______________

This does not:
_______________
#define M_OPplus(classname_macro) \
typedef classname_macro() \
operator+(const classname_macro()& rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};
_______________
yeh, you are right,
didn't carefully view the context

--
Thanks
Barry
Sep 14 '07 #5

P: n/a
Chris Thomasson wrote:
<sw*****@googlemail.comwrote in message
news:11**********************@y42g2000hsy.googlegr oups.com...
>if have simple macro defined this way:
#define M_OPplus( classname ) typedef classname operator+(const
classname& rhs);

and a template class :
template<typename X, typename Y>
class Test1
{
public:
double run();
M_OPplus( Test1<X,Y)
};
The compiler (VS2003) is complaining : warning C4002: too many actual
parameters for macro, . I think it is related to the comma in the
middle , the preprocessor may think that i am passing two parameters
to the macro.

Your correct.

>Is it possible to fix it and does it conform with the C++ standart?

Yes. You can use a little trick that involves passing a name of a macro
function to the M_OPplus macro which calls it to get at the tokens.
Something like this:
#define M_OPplus(classname_macro) \
typedef classname_macro() \
operator+(const classname_macro()& rhs)
template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
#define M_Test1 ....

definition and invocation should be identical
public:
double run();
M_OPplus(M_Test1);
};
See what I am getting at here?

--
Thanks
Barry
Sep 14 '07 #6

P: n/a
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
Chris Thomasson wrote:
[...]
>#define M_OPplus(classname_macro) \
typedef classname_macro() \
operator+(const classname_macro()& rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
#define M_Test1 ....

definition and invocation should be identical
[...]

I am not exactly sure what you mean here. Are you suggesting that 'M_Test1'
does not really need to be a macro function? Well, in that case the code
would need to be modified to something like:

____________
#define M_OPplus(classname) \
typedef classname \
operator+(const classname &rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1 Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};
____________
At first glance I thought that the 'M_Test1' macro would be expanded and
then passed to 'M_OPplus' which would produce the original error that the OP
was asking about. After I compiled it (gcc) I realized that it was getting
expanded in the context of the 'M_OPplus'.

I guess the only drawback from this would be that you could not pass the
'classname' parameter to another similar macro function. For instance:
this does not compile:
____________
#define M_Typedef(classname) \
typedef classname

#define M_OPplus(classname) \
M_Typedef(classname) \
operator+(const classname &rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1 Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};

____________

while this does:
____________
#define M_Typedef(classname_macro) \
typedef classname_macro()

#define M_OPplus(classname_macro) \
M_Typedef(classname_macro) \
operator+(const classname_macro()& rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};
____________
So I guess defining 'M_Test1' as a macro function instead of a plain macro
is more "flexible".
Any thoughts?

Sep 14 '07 #7

P: n/a
Chris Thomasson wrote:
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
>Chris Thomasson wrote:
[...]
>>#define M_OPplus(classname_macro) \
typedef classname_macro() \
operator+(const classname_macro()& rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
#define M_Test1 ....

definition and invocation should be identical

[...]

I am not exactly sure what you mean here. Are you suggesting that
'M_Test1' does not really need to be a macro function? Well, in that
case the code would need to be modified to something like:

I mean if you
#define M_Test1() ...
then call
M_Test1() other than M_Test1

if you
#define M_Test1 ...
then call
M_Test1 other than M_Test1()

--
Thanks
Barry
Sep 14 '07 #8

P: n/a
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
Chris Thomasson wrote:
>"Barry" <dh*****@gmail.comwrote in message
news:fc**********@aioe.org...
>>Chris Thomasson wrote:
[...]
>I am not exactly sure what you mean here. Are you suggesting that
'M_Test1' does not really need to be a macro function? Well, in that case
the code would need to be modified to something like:
[...]
I mean if you
#define M_Test1() ...
then call
M_Test1() other than M_Test1
Well, as soon as I call M_Test1() it will expand on the spot. I want to be
able to delay expansion until the exact place I need it. Therefore, I can
use the _name_ of the macro function M_Test1 as a sort-of function pointer.
This is the "trick" I mentioned to the OP...
Here is an example program you can compile:
_______________
#include <cstdio>

#define CALL_MACRO_FUNCTION(func_ptr)func_ptr()

#define MY_MESSAGE() "Press <ENTERto exit."

int main(void) {
puts(CALL_MACRO_FUNCTION(MY_MESSAGE));
getchar();
return 0;
}

_______________
As far as I can tell, this is 100% legitimate, and conforms to the standard.

Does that make sense to you?

Sep 14 '07 #9

P: n/a
Chris Thomasson wrote:
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
>Chris Thomasson wrote:
[...]
>>#define M_OPplus(classname_macro) \
typedef classname_macro() \
operator+(const classname_macro()& rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
#define M_Test1 ....

definition and invocation should be identical

[...]

I am not exactly sure what you mean here. Are you suggesting that
'M_Test1' does not really need to be a macro function? Well, in that
case the code would need to be modified to something like:

____________
#define M_OPplus(classname) \
typedef classname \
operator+(const classname &rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1 Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};
____________
At first glance I thought that the 'M_Test1' macro would be expanded and
then passed to 'M_OPplus' which would produce the original error that
the OP was asking about. After I compiled it (gcc) I realized that it
was getting expanded in the context of the 'M_OPplus'.

I guess the only drawback from this would be that you could not pass the
'classname' parameter to another similar macro function. For instance:
this does not compile:
____________
#define M_Typedef(classname) \
typedef classname

#define M_OPplus(classname) \
M_Typedef(classname) \
operator+(const classname &rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1 Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};

____________

while this does:
____________
#define M_Typedef(classname_macro) \
typedef classname_macro()

#define M_OPplus(classname_macro) \
M_Typedef(classname_macro) \
operator+(const classname_macro()& rhs)

template<typename X, typename Y>
class Test1 {
#define M_Test1() Test1<X,Y>
public:
double run();
M_OPplus(M_Test1);
};
____________
So I guess defining 'M_Test1' as a macro function instead of a plain
macro is more "flexible".

Well, forgive my English

You know

#define SOME_MACRO()

int main()
{
SOME_MACRO();
SOME_MACRO; // does not compile
}

so IMHO,
the definition and invoking of macro should better give the same form.

--
Thanks
Barry
Sep 14 '07 #10

P: n/a
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
Chris Thomasson wrote:
[...]
You know

#define SOME_MACRO()

int main()
{
SOME_MACRO();
SOME_MACRO; // does not compile
}
[...]

Your correct that it does not compile. However this does compile:

____________
#define CALL_IT(func_ptr)func_ptr()
#define SOME_MACRO()

int main(){
SOME_MACRO();
CALL_IT(SOME_MACRO);
return 0;
}

____________
See what I am getting at here?
Sep 14 '07 #11

P: n/a
Chris Thomasson wrote:
"Barry" <dh*****@gmail.comwrote in message news:fc**********@aioe.org...
>Chris Thomasson wrote:
[...]
>You know

#define SOME_MACRO()

int main()
{
SOME_MACRO();
SOME_MACRO; // does not compile
}
[...]

Your correct that it does not compile. However this does compile:

____________
#define CALL_IT(func_ptr)func_ptr()
#define SOME_MACRO()

int main(){
SOME_MACRO();
CALL_IT(SOME_MACRO);
return 0;
}

____________
See what I am getting at here?

I think I have to learn more about macro first.
thanks for your patience

--
Thanks
Barry
Sep 14 '07 #12

P: n/a
So do i,
thx anyway , i am going to test these tricks

Sep 14 '07 #13

This discussion thread is closed

Replies have been disabled for this discussion.