This cries out for a template.
class Example<class T>
{
...class definition...
};
The direct answer to the last part of your question - "given that I'm not in a macro definition any more, how do I get pasting and stringizing operators to work" - is "You can't". Those operators only work in macros, so you'd have to write macro invocations in order to get them to work.
Added:
@mackenir said "templates are not an option". Why are templates not an option? The code is simulating templates the old-fashioned pre-standard, pre-template way, and does so causing much pain and grief. Using templates would avoid that pain -- though there'd be a conversion operation.
@mackenir asked "is there a way to make things work with macros?" Yes, you can, but you should use templates - they are more reliable and maintainable. To make it work with macros, then you'd have to have the function names in the code in the included header be macro invocations.
You need to go through a level of indirection to get this to work correctly:
#define PASTE_NAME(x, y) PASTE_TOKENS(x, y)
#define PASTE_TOKENS(x, y) x ## y
#define TYPE_NAME Example
int PASTE_NAME(TYPE_NAME, _function_suffix)(void) { ... }
This level of indirection is an often necessary idiom for both tokenizing and stringizing operators.
Additional comments from @mackenir indicate continued problems. Let's make it concrete.
At the moment I am using a macro to define a bunch of fields and methods on various classes, like this:
class Example
{
// Use FIELDS_AND_METHODS macro to define some methods and fields
FIELDS_AND_METHODS(Example)
};
FIELDS_AND_METHODS is a multi-line macro that uses stringizing and token-pasting operators.
I would like to replace this with the following kind of thing
class Example
{
// Include FieldsNMethods.h, with TYPE_NAME preprocessor symbol
// defined, to achieve the same result as the macro.
#define TYPE_NAME Example
#include "FieldsNMethods.h"
};
OK. To make this concrete, we need a FIELDS_AND_METHODS(type)
macro that is multi-line and uses token-pasting (I'm not going to deal with stringizing - the same basic mechanisms will apply, though).
#define FIELDS_AND_METHODS(type) \
type *next; \
type() : next(0) { } \
type * type ## _next() { return next; }
With luck, this declares a member of the type 'pointer to argument type', a constructor for that type, and a method (Example_next in this case) that returns that pointer.
So, this might be the macro - and we need to replace it such that the '#include' does the equivalent job.
The content of fieldsNmethods.h becomes:
#ifndef TYPE_NAME
#error TYPE_NAME not defined
#endif
#define FNM_PASTE_NAME(x, y) FNM_PASTE_TOKENS(x, y)
#define FNM_PASTE_TOKENS(x, y) x ## y
TYPE_NAME *next;
TYPE_NAME() : next(0) { }
TYPE_NAME * FNM_PASTE_NAME(TYPE_NAME, _next)() { return next; }
#undef FNM_PASTE_NAME
#undef FNM_PASTE_TOKENS
Note that the header would not contain multiple-inclusion guards; its raison d'etre is to allow it to be included multiple times. It also undefines its helper macros to permit multiple inclusion (well, since the redefinitions would be identical, they're 'benign' and wouldn't cause an error), and I prefixed them with FNM_
as a primitive namespace control on the macros. This generates the code I'd expect from the C pre-processor. and G++ doesn't witter but produces an empty object file (because the types declared are not used in my example code).
Note that this does not require any changes to the calling code except the one outlined in the question. I think the question should be improved using the SPOT "Single Point of Truth" principle (or DRY "Don't Repeat Yourself"):
#define TYPE_NAME Example
class TYPE_NAME
{
// Include FieldsNMethods.h, with TYPE_NAME preprocessor symbol
// defined, to achieve the same result as the macro.
#include "FieldsNMethods.h"
};