Click here to Skip to main content
14,022,235 members
Click here to Skip to main content
Add your own
alternative version


15 bookmarked
Posted 3 Dec 2005

lstring - A lightweight wrapper for std::string

, 3 Dec 2005
Rate this:
Please Sign up or sign in to vote.
Simplify string handling with a wrapper for std::string.


Why should one write a wrapper for a standard C++ string?

  • Convenience: better usability through simplified interface.
  • Extensibility: add, remove, and enhance string functionality.


Motivating example

Assume that you are using std::string in your C++ program and you make a slight mistake, e.g. you erroneously think that the following code will insert "hello" at the beginning of str:

using namespace std;

void test1()
  string str ("world!");
  string hello ("Hello, ");
  str.insert (str.begin(), hello); // Error!!

Instead the compiler (VC 7.1) generates the following output:

myTestFile.cpp(12) : error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::_Myt
 ,_Ax>::size_type,const std::basic_string<_Elem,_Traits,_Ax>::_Myt &)' : canno
 t convert parameter 2 from 'std::string' to 'std::basic_string<_Elem,_Traits,
        No user-defined-conversion operator available that can perform this 
        conversion, or the operator cannot be called

The explanation is that 'std::string' is a typedef of template< class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_string. The traits and the Allocator template parameters have default values. But you cannot 'typedef away' a type in C++. A typedef is just an alias for the original type. You see the full basic_string template several times in the error message. By the way, with g++ 3.4 the same error produces an error message of more than 40 lines (reformatted to approximately 80 characters per line). You must have seen similar template jumble while using the C++ standard library. The length of the error messages multiplies when std::string is used as a template argument in another template, e.g. in std::vector<std::string> or in std::list<std::string>.

In the following, I use 'std::string' as a shortcut for std::basic_string<...> template.

Getting rid of templates

The basic idea is to write a string class (a class, not a template) that uses std::string as implementation 'back-end' to avoid the template mess and to make the string class extensible for the user. For now the interface is same as that of the std::string interface. Enter lstring, the lightweight string class.

The implementation looks similar to the following code:

class lstring {
// ...
  string_type imp; // explained below

  explicit lstring() {}
  lstring (const charT* s) : imp (s) {}
  lstring (const lstring& str) : imp (str.imp) {}

  lstring& operator= (const lstring& str)
                        { imp = str.imp; return *this; }
  lstring& append (const lstring& str)
                        { imp.append (str.imp); return *this; }
  size_type length() const  { return imp.length(); }
  size_type find (const lstring& str, size_type pos = 0) const
                        { return imp.find (str.imp, pos); }
  int compare (const lstring& str) const
                        { return (str.imp); }

// and dozens of other member functions ...
  • lstring contains no templates in the interface (almost)
  • Wrappers are provided for iterator and const_iterator; no namespace is used.
  • The implementation mostly forwards calls to the underlying std::string implementation 'back-end'.

I haven't explained what the string_type in the above code snippet means. string_type is the type of the underlying std::string. On Windows platform, string_type automatically adapts to Unicode (via _TCHAR) if _UNICODE is #defined.

class lstring
#if defined (_WIN32)
  typedef _TCHAR charT;
  typedef char charT;
  typedef std::basic_string<charT> string_type;
// ...

Much ado about nothing?

What have we gained by wrapping std::sting into a lightweight sting class? Let's first repeat the above example with lstring instead of std::string:

void test2()
  lstring str ("world!");
  lstring hello ("Hello, ");
  str.insert (str.begin(), hello); // Error!!

The output:

myTestFile.cpp(12) : error C2664: 'lstring &lstring::insert(lstring::size_typ
e,const lstring &)' : cannot convert parameter 2 from 'lstring' to 'lstring::
        No user-defined-conversion operator available that can perform this 
        conversion, or the operator cannot be called

This is still not the error message one expects but, because no templates are involved (i.e. no code generation from templates is involved), it's a lot better than the original std::string error message given above.

Customizing lstring

A second advantage of lstring is that it is not a std::string any more. This means that you can freely change the code and adapt it to your needs.

  • Extending lstring: Although lstring (like the Standard interface) contains a plethora of functions (e.g. 9 replace functions) there are always a few that you want to add, e.g. functions that convert an int to a lstring and vice versa, trim, pad and tokenize functions, or just constructors that take two, three, or more lstring arguments for fast string concatenation. Currently, the only extensions to the standard interface are the three swap() functions that efficiently let you exchange the contents of lstring with std::string.
  • Changing lstring: Do you prefer 'Redmond Style' or 'CamelCase' to STL style for class and function names? After a few 'search/replace' your code might look like this:
    LString myStr (_T("Hello"));
    ULONG pos = myStr.FindFirstOf (_T("lx"));
  • Removing functionality: Some people, for example, argue that a string class should contain minimum number of member functions and use STL-based algorithms instead ([1^], [2^], [3^]).

Using the code

The usage of lstring is not much different from std string:

#include <iostream>
#include "lstring.h"

#if defined (_UNICODE)
#  define std_cout  std::wcout
#  define std_cout  std::cout

using namespace std;

int main()
   lstring hello (_T("Hello, world!"));
   std_cout << hello << endl;


Many interesting string articles and implementations can be found in the CodeProject MFC/C++ String section.


The main purpose of lstring is to make string handling easier with standard C++-like string class, implemented as a wrapper for std::string (also known as std::basic_string). lstring also serves as a basis for user defined enhancements and adaptations. A set of unit tests is also included. In the forthcoming article, I will describe the customization of a standard container.


  • December 4th, 2005 - First release in CodeProject.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Roland Pibinger
Web Developer
Austria Austria
No Biography provided

You may also be interested in...

Comments and Discussions

NewsArticle views lost :-( Pin
Roland Pibinger29-Dec-05 9:36
memberRoland Pibinger29-Dec-05 9:36 
GeneralNice work! Pin
spih20054-Dec-05 18:12
memberspih20054-Dec-05 18:12 
GeneralRe: Nice work! Pin
Roland Pibinger5-Dec-05 7:49
memberRoland Pibinger5-Dec-05 7:49 
Thank you! Smile | :)
GeneralI like this. Pin
Nemanja Trifunovic4-Dec-05 14:36
memberNemanja Trifunovic4-Dec-05 14:36 
AnswerRe: I like this. Pin
Roland Pibinger5-Dec-05 8:03
memberRoland Pibinger5-Dec-05 8:03 
GeneralRe: I like this. Pin
qwerty666@codeproject.com7-Dec-05 15:50
memberqwerty666@codeproject.com7-Dec-05 15:50 
AnswerRe: I like this. Pin
Roland Pibinger8-Dec-05 5:28
memberRoland Pibinger8-Dec-05 5:28 
GeneralRe: I like this. Pin
Peregrine Falcon9-Dec-05 8:41
memberPeregrine Falcon9-Dec-05 8:41 
GeneralRe: I like this. Pin
WREY11-Dec-05 8:22
memberWREY11-Dec-05 8:22 
GeneralRe: I like this. Pin
qwerty666@codeproject.com11-Dec-05 10:52
memberqwerty666@codeproject.com11-Dec-05 10:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190417.4 | Last Updated 4 Dec 2005
Article Copyright 2005 by Roland Pibinger
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid