You could make the parameter a std::future
, and go with the simple derived approach.
Or instead of string, pass in a proxy or a function that can provide it.
Or turn the table around, pass nothing and have a member function in Base that returns the string as it would be created.
Another approach is to have a virtual predicate function to the feature: in your base class it returns false, others return true, so you can call it before the real work doing. Alternatively it could return a pointer-to-function for the implementation, if it's likely to be doable in a static function. (And this can be passed as another param...)
It would be interesting to read you research concluding vtables out.
Templates only help you if you can tell the target at compile time. The problem as you stated it implies processing information that appears only at runtime. And that requires some pointers or other information actually passed around. But you might come up with a refined description of the problem.