简体   繁体   中英

C++ Macro riddle: Printing the name of the TYPE

In a macro I can use xxxx_##TYPE and ##TYPE##_xxxxx to have the TYPE name filled in correctly, but I can't use ##TYPE## in the middle of a string eg (print "##TYPE## is the name of the type";)

Is there a way around it?

You can do this by combining two features. One is ''stringification'', whereby a macro argument is converted to a string by prefixing it with # . (This is related to, but different from, the ''token-pasting'' operator ## that you're obviously already familiar with.) The other is the fact that C++, when given multiple string literals in a row, will combine them into a single string. For example, "a" "b" "c" is equivalent to "abc" . I'm not clear on exactly how your macro is to be defined, so I can't show you exactly what to type, but a full explanation and some good working examples are at http://gcc.gnu.org/onlinedocs/cpp/Stringification.html .


Edited to add a simple example, at Kleist's request. This program:

#include <stdio.h>

#define PRINT_WHAT_THE_NAME_OF_THE_TYPE_IS(TYPE) \
  printf("%s\n", "'" #TYPE "' is the name of the type.")

int main()
{
  PRINT_WHAT_THE_NAME_OF_THE_TYPE_IS(Mr. John Q. Type);

  return 0;
}

will print this:

'Mr. John Q. Type' is the name of the type.

(This will run in either C or C++. The reason I wrote it C-ishly is that in my experience these sorts of preprocessor tricks are more common in C code than in real C++ code; but if you wanted to use std::cout << instead of printf , you absolutely could.)

## is the token pasting operator and it takes two different tokens and pastes them together to make a single token. The entire string literal is considered a single token, thus the pasting operator doesn't work within it. See http://gcc.gnu.org/onlinedocs/gcc-4.0.4/cpp/Tokenization.html

String literals will be concatenated when they are next to each other.

#define QUOTE(X) #X

#define DOSTUFF(TYPE) \
    void print_ ## TYPE () { \
        static const char *str = QUOTE(TYPE) " is the name of the type\n"; \
        printf(str); \
    }

DOSTUFF(Foo);

int main(int argc, char ** argv) {
    print_Foo();
    return 0;
} 

Output of g++ -E -c main.cpp will show you what this gets preprocessed into.

# 16 "main.cpp"
void print_Foo () { 
  static const char *str = "Foo" " is the name of the type\n"; 
  printf(str); 
};

int main(int argc, char ** argv) {
 print_Foo();
 return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM