edit: You can put tBuf in the printMe function if you know the max size of the flash string. That way the tBuf array memory is allocated only when the printMe function is called, and released when it exits.
By the way, I'm not married to the idea of using __FlashStringHelper. If there's a better way to do what I'm trying to do (create instances of objects with constant strings in PROGMEM) then I'm all ears.
Two choices: PROGMEM or __FlashStringHelper. If variable is defined with PROGMEM/__FlashStringHelper and parameter is required opposite __FlashStringHelper/PROGMEM you have to use reinterpret_cast to avoid instruction overhead. You can use both types of function in program: Serial.print like and also printf_P like.
I think it's easier to make the PSTR use a lambda expression instead of compiler extensions. This allows you to use it at global scope:
PieterP:
The default PSTR macro (program memory string) uses exotic compiler extensions, so you can't use them outside of functions, but luckily, you can circumvent this using a lambda expression:
#undef PSTR
#define PSTR(s) ([]{ static const char c[] PROGMEM = (s); return &c[0]; }())
const auto foo = F("I am a string in PROGMEM");
const auto bar = "I am a string in RAM";
The type of "foo" will be "const __FlashStringHelper * const" in this case.