You aren't calling them strings, but they are. I didn't specify "NUL-terminated ASCII" or anything like that. Call them S-expressions if you prefer. It makes no difference.
C++ can manipulate itself. Granted, you'll want a library such as LLVM, but you can get the job done yourself if you are a glutton for punishment.
Code is represented via data structures on normal (von Neumann) hardware. LISP is every bit as compiled as C++. Both forms of C++, human-readable and compiled, can be manipulated. It's the same as LISP, except that "human readable" is debatable for any form of LISP.