I've asked this question in two other places, but have received very limited feedback, so I'm extending my audience.
Attend, for my problem is not easy to understand.

It is about the CornedString library which I'm going to write.

Preface
Examining some large open source projects such as Mozilla shows that often, programmers want very specfic storage semantics for their string class. They may want, for example, employ a copy-on-write technique for sharing values between string objects. Or they might want their string objects to have a small internal buffer to avoid heap allocations for small objects. There are very many strategies in implementing strings, and all have advantages and drawbacks.
The std::string class does not have specific requirements on its storage semantics. Library writers are free to implement it however they want. The library that comes with MSVC++.Net 2003, for example, employs a 64-bit internal buffer for short strings. The GNU C++ library uses reference counted strings with copy-on-write. One drawback of that approach is that it is not thread-safe.
As a result, projects repeatedly implement their own specific string classes. This has quite a few drawbacks:
1) Extended development time for additional coding, testing and debugging.
2) Incompatible string classes between projects make transferring code hard.
3) Library solutions are more reliable because more than one group does the testing.
4) A string class written as part of a larger program is often less efficient than one from a library, because it is given less attention.

CornedString
All these reason suggest that there ought to be a library of various string implementations, all with clearly defined storage semantics, for broad use.
My design goals in this library were speed, interoperability and adherence to the requirements on std::string (so that, in theory, any one of these classes could be used as a compliant std::string implementation). Another design goal is that std::string can be treated like any other part of the library.

Common Base?
When you have multiple classes that all share the same interface, you might be tempted to offer an abstract base class for all of them, which offers a consistent interface. This would have the advantage that passing any of the derived classes to a generic function is very easy, just use a reference to the common base as parameter type:
Code:
void generic_function(const string_base &str);
This has drawbacks, though. First, it requires a virtual destructor of the classes. Such a thing is not planned in the standard.
Second, std::string does not derive from that base, so it could not be used the same way as any other of these classes.
Third, it adds the overhead of a vptr to the class, which is not acceptable for the speed requirements.
We need to find a different solution.

External vPtr
There are three ways of parameter passing that my alternative way must support: pass-by-value, pass-by-reference and pass-by-const-reference. Since the classes must not have a common base, I can't use traditional means for this.
Instead, I created three different wrapper classes for these three ways. These are any_string (pass-by-value), any_string_ref (pass-by-ref) and any_string_const_ref (pass-by-const-ref).
Any kind of object that is interface-compatible with std::string can be assigned to these three classes. The technique used for this is the same that Boost.Any uses. Effectively, I create a vTable for these objects and wrap an object that contains nothing but a vPtr around the actual string object.
Uhuh. Let me show you some pseudo-code of how this is done:
Code:
class any_string
{
  class holder_base
  {
  public:
    virtual do_something() = 0;
  };
  template <typename Str>
  class holder : public holder_base
  {
    Str held;
  public:
    holder(const Str &s) : held(s) {}
    virtual do_something() {
	  held.do_something();
	}
  };

  holder_base *held;
public:
  void do_something() {
    held->do_something();
  }

  template <typename Str>
  any_string(const Str &s) {
    held = new holder<Str>(s);
  }
};
When any_string is assign an object, it allocates an appropriate subclass of holder_base and stores the value in there. Since holder only holds its vptr and an object of the stored type, I've effectively wrapped a vptr around the stored object. This is why I call the technique external vptr.


My Problem
So far, so good. However, this raises an interesting problem regarding the semantics of operator =.
Here's the declaration of operator =:
Code:
class any_string { //...
  any_string &operator =(const any_string &rhs);
};
The implementation is what worries me.
In a normal string, there is one level of indirection: the string objects redirects operations to its buffer, where the actual character data resides. It is thus quite obvious that an assignment to the string ought to change the character data in the buffer.
any_string has two levels of indirection: the any_string object redirects operations to its held object, which in turn redirects them to its buffer.
operator = may be a special case though. My question is, should I, as the any_string, redirect the assignment to the held object, so that the character buffer gets replaced? Or should I replace the held object itself?
I am unsure which to do. Any and all input is highly appreciated.