I would like to attach MyNamespace:: to the function defined by the macro:
#define transFunc(func) \
dimensionedScalar func(const dimensionedScalar& ds) \
{ \
if (!ds.dimensions().dimensionless()) \
{ \
FatalErrorIn(#func "(const dimensionedScalar& ds)") \
<< "ds not dimensionless" \
<< abort(FatalError); \
} \
\
return dimensionedScalar \
( \
#func "(" + ds.name() + ')', \
dimless, \
MyNameSpace::##func(ds.value()) \
);
\
}
But When I call
transFunc(Foo)
the compiler throws the following error :
pasting "::" and "Foo" does not give a valid preprocessing token
What is wrong about the way I concatenate tokens above?
The ##
works for macros, It doesn't meant to work in a regular code.
You can do it as follows:
#define ADD_NAMESPACE(NS,FUNC) NS##::##FUNC
Now you can use it like this:
ADD_NAMESPACE(std,cout)<<x1<<ADD_NAMESPACE(std,endl);
But you can't do like this:
std ## :: ## cout<<std ## :: ## endl;
You just do:
std::cout<<std::endl;
EDIT
this example worked with gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC):
#include <iostream>
#define ADD_NAMESPACE(NS,FUNC) NS##::##FUNC
int main()
{
ADD_NAMESPACE(std,cout)<<"hello world!"<<ADD_NAMESPACE(std,endl);
return 0;
}
##
is used to bodge two tokens together to make a single token. So something like func##1
would expand to the single token func1
.
Using it here, it tries to bodge together ::
and Foo
to make a single token ::Foo
. As the error says, that's not a valid token. You don't want a single token here; you just want to keep the two tokens separate:
MyNameSpace::func(ds.value())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With