Click here to Skip to main content
Click here to Skip to main content

A TCHAR style header file for STL strings and streams

By , 11 Feb 2006
 

Introduction

I had asked on the Visual C++ forum if there was a standard header file that would provide a way of declaring std::strings so that a single code source could be compiled in either ANSI or UNICODE builds without any changes, much in the same way tchar.h is used. The response I got back is that there is no standard way of doing this so I decided to write my own header file to accomplish this task.

The TSTL.H header file

The header file is a simple one that uses a series of typedefs to define new synonyms for some of the commonly used STL classes that use chars and wchar_ts. The idea being that you can now use new names wherever you would have previously had to use either one or the other of the standard names. For example, a piece of code may have been written:

#ifdef _UNICODE
   std::wostringstream stream;
   stream.setf(std::wios::fixed);
#else
   std::ostringstream stream;
   stream.setf(std::ios::fixed);
#endif

and can now be written:

std::tostringstream stream;
stream.setf(std::tios::fixed);

and it will compile in either ANSI or Unicode builds. The file is probably not complete as there may be other STL classes that I do not know about or did not think of that should be included in this file. If there are, let me know which ones and I can include them and update the file.

To use the file, simply include it in your precompiled header file (stdafx.h) or include it in any file that uses any of the STL string or stream classes. The file is listed here and it can be downloaded from the download link at the top of this article.

// tstl.h - header file for TCHAR equivalents of STL
//          string and stream classes
//
// Copyright (c) 2006 PJ Arends
//
// This file is provided "AS-IS". Use and/or abuse it
// in any way you feel fit.
// 
 
#pragma once

#include <string>
 
namespace std
{
#if defined UNICODE || defined _UNICODE
 
    typedef wstring         tstring;
 
    typedef wstringbuf      tstringbuf;
    typedef wstringstream   tstringstream;
    typedef wostringstream  tostringstream;
    typedef wistringstream  tistringstream;
 
    typedef wstreambuf      tstreambuf;
 
    typedef wistream        tistream;
    typedef wiostream       tiostream;
 
    typedef wostream        tostream;
 
    typedef wfilebuf        tfilebuf;
    typedef wfstream        tfstream;
    typedef wifstream       tifstream;
    typedef wofstream       tofstream;
 
    typedef wios            tios;
 
#   define tcerr            wcerr
#   define tcin             wcin
#   define tclog            wclog
#   define tcout            wcout
 
#else // defined UNICODE || defined _UNICODE
 
    typedef string          tstring;
 
    typedef stringbuf       tstringbuf;
    typedef stringstream    tstringstream;
    typedef ostringstream   tostringstream;
    typedef istringstream   tistringstream;
 
    typedef streambuf       tstreambuf;
 
    typedef istream         tistream;
    typedef iostream        tiostream;
 
    typedef ostream         tostream;
 
    typedef filebuf         tfilebuf;
    typedef fstream         tfstream;
    typedef ifstream        tifstream;
    typedef ofstream        tofstream;
 
    typedef ios             tios;
 
#   define tcerr            cerr
#   define tcin             cin
#   define tclog            clog
#   define tcout            cout
 
#endif // defined UNICODE || defined _UNICODE
} // namespace std

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

PJ Arends
President
Canada Canada
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generaltypedef vs #definestaffNishant Sivakumar12 Feb '06 - 3:18 
Hey PJ
 
How come you mixed and used both in your generic header?
 
Regards,
Nish
 

GeneralRe: typedef vs #definememberRama Krishna Vavilala12 Feb '06 - 5:34 
wcerr, wcout, wcin etc are objects so he has to use #define: he cannot use typedef.

 


Member in good standing - the great cult of Firefox at CP
 

GeneralRe: typedef vs #definestaffNishant Sivakumar12 Feb '06 - 5:41 
Rama Krishna Vavilala wrote:
wcerr, wcout, wcin etc are objects so he has to use #define: he cannot use typedef.

 
Yes, but why did he choose not to use #define for everything? The tchar.h macros use #define, so I was wondering why PJ went for a deviation there.
 
Regards,
Nish
 

GeneralRe: typedef vs #definememberPJ Arends12 Feb '06 - 6:11 
tchar.h uses #define to rename the c string functions, but uses typedef to declare the TCHAR types. Use typedef to rename data types and class types, use #define to rename non-types such as objects, functions and constants.

 


"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
 
"Obviously ???  You're definitely a superstar!!!" - mYkel - 21 Jun '04
 
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
 
Within you lies the power for good - Use it!
GeneralRe: typedef vs #definestaffNishant Sivakumar12 Feb '06 - 8:14 
Thanks PJ.
 
Regards,
Nish
 

GeneralRe: typedef vs #definememberRama Krishna Vavilala12 Feb '06 - 6:12 
I don't know about PJ's reasons, but I normally do typedef because I hate #define's. Also, intellisense is lost (not checked in VS2005) if you do #defines instead of using typedef's.
 


Member in good standing - the great cult of Firefox at CP
GeneralRe: typedef vs #definememberAnders Dalvander12 Feb '06 - 21:18 
Why not use references?
#if defined UNICODE || defined _UNICODE
wostream& tcout = wcout;
wostream& tcerr = wcerr;
wostream& tclog = wclog;
wistream& tcin = wcin;
#else
ostream& tcout = cout;
ostream& tcerr = cerr;
ostream& tclog = clog;
istream& tcin = cin;
#endif

 
// Dalle
GeneralRe: typedef vs #definemembertoxcct13 Feb '06 - 0:29 
performance reason...
 

TOXCCT >>> GEII power
[toxcct][VisualCalc 2.20][VCalc 3.0 soon...]
GeneralRe: typedef vs #definememberAnders Dalvander13 Feb '06 - 0:35 
Heh, I think you need a profiler to back that up... Poke tongue | ;-P
GeneralRe: typedef vs #definemembertoxcct13 Feb '06 - 0:38 
why ?
using references implies that there is a declaration, an affectation, and then type checking (which slows down), while using #defines is a preprocessor treatment... (so none of the cases quoted above).

 

TOXCCT >>> GEII power
[toxcct][VisualCalc 2.20][VCalc 3.0 soon...]
GeneralRe: typedef vs #definememberPJ Arends13 Feb '06 - 6:43 
Like I said in my reply to Roland below, I am here to learn. If you can show me code that works the way you propose, that does not involve cpp, lib, or dll files that have to be added to the project (I want a simple header file that I can place in my global include directory) and where I can use the syntax std::tcout etc. then I am all eyes. I have found that using #define fits my requirements exactly.
 


"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
 
"Obviously ???  You're definitely a superstar!!!" - mYkel - 21 Jun '04
 
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
 
Within you lies the power for good - Use it!
GeneralRe: typedef vs #definememberLing, Xiao-li28 Feb '07 - 0:25 
Hi, PJ Arends, thanks, you did a good job.
 
Nishant Sivakumar wrote:
Hey PJ
 
How come you mixed and used both in your generic header?
 
Regards,
Nish

 
I think only those who familiar with MFC/Windows programming style can fully understand PJ's solution. Really, I don't want to offense Nishant Sivakumar.
GeneralSome RemarksmemberRoland Pibinger12 Feb '06 - 0:59 
You should not put something into namespace std. This namespace is not available for mere mortals. Smile | :) In general, put your names only in your own namespace(s). In this case it may even be better to use no namespace at all.
 
namespace pja 
{
#if defined UNICODE || defined _UNICODE
 
    typedef std::wstring tstring; // std:: here 
//...
}
 
Also, include the necessary iostream header files (maybe the lightweight <iosfwd> is sufficient).
 
Otherwise your approach seems to be practical. I've used a similar solution in http://www.codeproject.com/string/lstring.asp[^]
GeneralRe: Some RemarksmemberPJ Arends12 Feb '06 - 6:33 
I actually did not "add" anything to the std namespace, I just renamed a few things. Unsure | :~
 
The reason I did it this way is because when I use the STL classes I like to preface the class name with std::, ie I prefer to see std::string in my code rather than simply string. By declaring the typedefs this way I can preseve that.
 

Roland Pibinger wrote:
Also, include the necessary iostream header files (maybe the lightweight is sufficient).

 
I did include <string> which indirectly includes <iosfwd>, among others. But you are probably right that a direct inclusion is probably better.
 

Roland Pibinger wrote:
I've used a similar solution in http://www.codeproject.com/string/lstring.asp[^]

 
And I looked at your class before I embarked down this road. Your class works well, but it only wraps the string class. What about all the stream classes? I figured by the time I wrapped all the stream classes the same way you wrapped the string class i would end up with a header file a couple hundred KB in size. There had to be a better way, and I think this is it.
 
I posted this class to both share what I learned, and to hopefully improve by having others critique it.
 


"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
 
"Obviously ???  You're definitely a superstar!!!" - mYkel - 21 Jun '04
 
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
 
Within you lies the power for good - Use it!

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 12 Feb 2006
Article Copyright 2006 by PJ Arends
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid