ChatGPT解决这个技术问题 Extra ChatGPT

What does ## (double hash) do in a preprocessor directive?

#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;

The above line is take from Unreal 4, and I know I could ask it over on the unreal forums, but I think this is a general C++ question that warrants being asked here.

I understand the first line defines a macro, however I am not well versed in preprocessor shenanigans in C++ and so I'm lost over there. Logic tells me the backslash means the declaration continues onto the next line.

FThreadSafeStaticStat looks a bit like a template, but there's #'s going on in there and a syntax I've never seen before in C++

Could someone tell me what this means? I understand that you may not have access to Unreal 4, but it's just the syntax I don't understand.

You can read about ## operator on cppreference, among other things
## is/could be called the concatenation operator.
Oh, that's pretty cool! It explains rather a lot, thanks. But why is the struct keyword used? The line looks more like a variable definition
The struct introduces an elaborate type specifier as far as I can tell.
The official name is "token pasting operator" because it combines two preprocessing tokens to produce another. Note that it is only valid if the result is a valid preprocessing token, e.g. you can't do + ## 3 to make +3. (But you can do + 3 of course, without the operator)

S
Susam Pal

## is the preprocessor operator for concatenation.

So if you use

DEFINE_STAT(foo)

anywhere in the code, it gets replaced with

struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;

before your code is compiled.

Here is another example from a blog post of mine to explain this further.

#include <stdio.h>

#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
    printf("Stumped?\n");
}

This program would compile and execute successfully, and produce the following output:

Stumped?

When the preprocessor is invoked on this code,

begin is replaced with decode(a,n,i,m,a,t,e)

decode(a,n,i,m,a,t,e) is replaced with m ## a ## i ## n

m ## a ## i ## n is replaced with main

Thus effectively, begin() is replaced with main().


h
hmofrad

TLDR; ## is for concatenation and # is for stringification (from cppreference).

The ## concatenates successive identifiers and it is useful when you want to pass a function as a parameter. Here is an example where foo accepts a function argument as its 1st argument and the operators a and b as the 2nd and 3rd arguments:

#include <stdio.h>
enum {my_sum=1, my_minus=2};
#define foo(which, a, b) which##x(a, b)
#define my_sumx(a, b) (a+b)
#define my_minusx(a, b) (a-b)

int main(int argc, char **argv) {
    int a = 2;
    int b = 3;
    printf("%d+%d=%d\n", a, b,  foo(my_sum, a, b));  // 2+3=5
    printf("%d-%d=%d\n", a, b, foo(my_minus, a, b)); // 2-3=-1
    return 0;
}

The # concatenates the parameter and encloses the output in quotes. The example is:

#include <stdio.h> 
#define bar(...) puts(#__VA_ARGS__)
int main(int argc, char **argv) {
    bar(1, "x", int); // 1, "x", int
    return 0;
}