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

cpp_noname picture cpp_noname · Dec 8, 2014 · Viewed 9.6k times · Source

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?

Answer

Mike Seymour picture Mike Seymour · Dec 8, 2014

## 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())