We are working with an internal library that has the StringBuilder class, which is used to convert a list of VariableValue objects to a string. VariableValue objects can be constructed from arbitrary types (by specializing the convertVariable template convertVariable ). Here is the code describing the scenario:
struct VariableValue {
All this was very good. Clients simply had to provide the appropriate specialization for the convertVariable template (our library already provides many specialties for different types), and then StringBuilder can be used. Nearly.
The problem is that it does not work with types that cannot be copied. All template functions take their argument by value. And in the case of the convertVariable template, convertVariable quite difficult to change the signature (because there are quite a few specializations). Therefore, even if I can make the StringBuilder::operator<< template occupy const T & , this will not help, since the convertVariable instance will only be called with T (since the reference-to-const part is deleted during template type output). If I fix this by specifying the type explicitly, as in:
class StringBuilder { public: // ... template <class T> StringBuilder &operator<<( const T &v ) { return *this << convertVariable<const T &>( v ); } };
The component will complain because it no longer finds old specializations (for example, template <> VariableValue convertVariable( int ) ), since it is looking for specializations that take a const-reference.
Does anyone know how I can customize the StringBuilder class StringBuilder that I can pass non-copyable objects (that is, objects whose type does not allow you to create copies or assign copies) to the operator<< function?
source share