Well, I was pursuing a re-use code design, so it forwards call deeper into the class as a result.Your copy-constructor is very contrived and inefficnent...
I guess, but it's an easy algorithm to make sure I have enough space for the buffer and add some more so we don't reallocate all the time.Starting from that call to PrepareBuffer is where it gets really nasty. Why would the nNeededSize you pass in ever care about the current length? Why is the new size allocated the length of the right hand string*2 plus 2 plus the default size*2? That's pretty excessive!
Reusing code and well... the destructor is supposed to delete/get rid of the buffer, so calling that would take care of that. Save duplicating code was my motive.Then you do the unthinkable and call the destructor directly. Sure you're allowed to do that, but Ewwww! The only useful thing the destructor does is delete  m_pData so why not just do that?
Basically, code reuse. Truncate the current buffer and then call += which does the real job. And since there's no data, it appends to the start.I can't work out why Assign would call Empty then operator +=.
In other words, just call specialized templates to do the actual code instead of acquiring a function pointer?It does not make sense for the 1 parameter version of GetLength, GetFormatFunction, GetVFormatFunction, GetVFormatCountFunction, and GetCompareFunction to be member template functions. You've totally mixed up how to do that. What you want is for example with GetCompareFunction, a default template that provides no implementation. Then you provide specialisations with the template<> syntax where instead of using the type in any way at all you use char and wchar_t.
Yeah, I remembered MFC did the same and figured it would be better to make sure there was appropriate space so that I didn't have to reallocate each time I had to copy.I'm glad you've done the two-pass approach for your Replace function.