std::string itself does not.
There are various alternatives, more or less elegant and more or less pros and cons. Let me try to compare them.
encapsulation completion
Perhaps the cleanest solution is to create a class containing std :: string, and which can accept commands and assignments that perform the conversion.
- problem: std :: sting has over a hundred methods: if you want your class to expose all of them ... be prepared to write all the hose functions just to call wrapped ones. This is a pure "performance" problem, which is not, is not, apparently, OOP cares ... maybe they are paid for with a typed character ... :-)
- advantage: no run-time polymorphism (not supported by std :: string) can accidentally work, so the code is more secure.
"partial" packaging
Same as before, but applies only to some important methods or requires some explicit coding.
A typical implementation may be:
may be:
class llstring { public:
This class itself is incapable of any algorithm and operation, but can participate in any type of std::string by calling str() . And it can accept any std :: string result, getting the conversion.
Probably a good compromise between transcoding and maintenance risks
Hereditary
std :: string as a base, not a member. The code is similar to the above (you must provide a conversion method when building or assigning)
advantages: the interface and behavior of orioginal std :: string are automatically displayed, therefore all methods of std :: string work and are available.
neutral: both conversion forward (by design) and backward (by basic inheritance) from std :: string work. This can lead to some ambiguity with some operations that may not go through llstring. This is not a problem in itself, but you must be sure how the name resolution and name binding will be performed. The jaguar is well indicated, but it is one of the sides of the language that is not always known to any average programmer.
disavantage: llstring exposes a polymorphic behavior towards std :: string, which does not behave politically to llstring (no methods are virtual, including a destructor), so you should never call delete on std :: string * (this is Undefined Behavior, if it points to "llstring").
Given that both llstring and string are value types, this usually should not happen (for 30 years I have never written a single new std::string or delete pstring ). But this in any case will catch all the tirades of the OOP fanatist, claiming the classical OOP rules, to apply to strings, even if they are not an object of OOP.
But there is another -IMHO more subtle risk: in the composite expression between llstring and the string, all intermediate results will be string. And the intermediate operation will not convert between them. And all this is implicit. Again, the language specification is well defined, but it can be tricky to take control of everything. A search for an intermediate result that has not yet been assigned may fail ... due to an unexpected capital letter inside.
Inverse transformation
Not exactly what you asked for, but ... maybe it's better to deal with the problem.
Instead of "convert when replacing the destination", "convert when leaving the source":
write a wrapper (for example, in the section "partial deformation", above), instead of implicitly converting a string from and having an explicit function str (), it takes an explicit construct from n strings (even without conversion) and has an implicit string conversion to ( operator std::string() { return lowercase(m); } )
It works the opposite, as you requested. Itβs good if the number of points at which the existence of header lines is allowed has little respect for the common lines in your program (which you can always consider to be lowercase), and if you can provide that all the std :: string operations you can implement are string values case will never be generated in uppercase.
Edit: char_traits solution
Added after Nawaz post :
The solution will try to change the behavior. (not value ) by making char stick to different semantics.
- Advantage: Simple and does not require large wrappers. Fast coding.
- Disavantage: may not be exactly what it was intended: since the std :: string functions are available, and since the copy may not be the only way to change the string contents, you are not provided (in any case) that the characters in it will never be capitalized. If you cannot provide this copy, this is the only way to change the string value.
Note: just like string , char_traits does not have a virtual destructor, but, unlike a string, no OOP resident usually shouts about inheritance from it. And if they ask him, they will most likely say: "There will be no dynamic allocation to char_traits." Goodbye coherence.
Finally
There is no "perfect solution" with a "low cost." All of them are somehow ineffective at some stage.