F() takes immutable string literals, that are known at compile time, and places them into flash ("PROGMEM") instead of RAM.
snprintf() creates strings at runtime and places them into a mutable array. The two things are fundamentally incompatible.
Limited compile-time concatenation
A very limited form of what you're trying to do could probably done like this:
#define MY_STRINGIZE(x) #x
myMethod(F("There are " MY_STRINGIZE(60) " seconds in a minute"));
This expands to:
myMethod(F("There are " "60" " seconds in a minute"));
Adjacent string literals are concatenated together, which makes this:
myMethod(F("There are 60 seconds in a minute"));
All that said, you could just write 60 in there directly. And there's none of
snprintf's formatting capabilities possible here.
There is not a compile-time version of
snprintf available in Arduino. And I don't think the features of the C++ (or C) language are there to support the creation of one either. Odds are there is a better way of achieving what you really want to do.
Working around this altogether
Often it's not necessary to concatenate strings at all, particularly if you're just to turn around and write them to a
Stream, or more generally
Print subclass, e.g.
SoftwareSerial, etc. Concatenating things for you is a large part of what these do. It is not necessarily to do it yourself in advance.
If you have a string literal and constant (or variable) and want to keep as much of it out of RAM as possible, using two separate
.println() helps you do this:
"AT+CIPSTAT=" into flash.
- If index is a constant it will also wind not being resident in RAM.
I realize you're asking about, getting as much into flash as possible, but I also can't help but point out this same basic technique applies to this otherwise awful idea, for somewhat different reasons:
Serial.println(String(F("Key ")) + keyname + " : " + value);
This creates a horrific mess of allocations and deallocations and unnecessary copying, where if you just let the Stream/Print object do its job by calling
println() multiple times. The result code is more reliable, smaller, and where not I/O-bound, faster when you do.