The problem is I don't understand why those should be separate. Why not use one class, like CharType, that would contain both the logic of char traits and char type. I mean replace that:
template <class _Elem, class _Traits = char_traits<_Elem>, class _Alloc = allocator<_Elem>>
class basic_string { /*...*/ };
with that:
template <class ExtendedTraits, class _Alloc = allocator<_Elem>>
class basic_string { /*...*/ };
where ExtendedTraits is the presaid combination of _Elem and _Traits, that might look like that:
template<_CharType> //all the necessary template parameters
class extended_traits
{
public:
using value_type = _CharType;
private:
_CharType _elem;
public:
//... all methods, that used to be in char_traits but now non-static and accepting one parameter
};
I tried to implement both approaches, both of them do work, but there may be some problems I still do not notice.
I think it makes more sense to separate the character type from the
Traits
object.Traits
is an additional class for character comparisons and such, which is inherently different from the character type. Your method would work, but the equivalent would be like combining two completely different functions into the same function.It's also more immediately obvious what character type the string is using. For example:
is much more obvious than
as there is an additional level of nesting and more characters and such.
At the end of the day, we don't care about what
Traits
is, we care about what character type the string is.Traits
is for internal operations, and is meant to be abstracted away; as such, it's kept away from the character type, which is meant to be more obvious as it indicates what types of values the string can contain.At least, that's my view on things.
Besides, it's not necessarily a bad thing to have more template arguments for
std::basic_string
, especially since there's only ever one template argument you really need to define a parameter for - the other template are given default types. It's not often that I would need to define my ownTraits
class. But if I wanted to define my own separate string class with a custom character or something like that, I would have to define aTraits
class for it, even if I have written my assignment operator and comparison operators and everything else. That would be especially irritating.