Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pasting "::" and "Foo" does not give a valid preprocessing token

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?

like image 823
cpp_noname Avatar asked Dec 08 '14 15:12

cpp_noname


Video Answer


2 Answers

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;
}
like image 35
SHR Avatar answered Nov 03 '22 01:11

SHR


## 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())
like image 60
Mike Seymour Avatar answered Nov 03 '22 00:11

Mike Seymour