views:

98

answers:

3

We've got a bunch of legacy code that doesn't support Unicode, so a transitional pattern we use in our code is to move the function to a .inl file, change char to CHAR_TYPE, and then wrap it up like this:

#define CHAR_TYPE wchar_t
#define STRING_TYPE std::wstring
#define MyFunctionName MyFunctionNameW
#include "MyFunction.inl"

#undef CHAR_TYPE
#define CHAR_TYPE char
#undef STRING_TYPE
#define STRING_TYPE std::string
#undef MyFunctionName
#define MyFunctionName MyFunctionNameA
#include "MyFunction.inl"

...where MyFunction.inl then defines MyFunctionName, using the macros to generate both an 'A' version and a 'W' version.

This is icky, but it's unfortunately necessary until we get all of our code converted to support Unicode.

Is there an alternative way I could do this with templates? I'm thinking that something like the following would be nice:

typedef MyFunctionName<wchar_t, std::wstring> MyFunctionNameW
typedef MyFunctionName<char, std::string> MyFunctionNameA

Is this possible?

+4  A: 

Update: I misread the question, thinking you already had A and W functions written which you wanted to call through the same name. What you have is indeed a situation for which templates are designed, but I won't repeat the correct answer.

Simple overloading works, no need for templates or additional complexity. The Win32 API uses macros because C doesn't have overloading.

inline
void MyFunctionName(std::wstring const& value) { MyFunctionNameW(value); }
inline
void MyFunctionName(std::string const& value) { MyFUnctionNameA(value); }
Roger Pate
That doesn't help at all, if the original function signature is something similar to char MyFunctionName(int x, float y);
Paulius Maruška
If the functions only differ in return type, templates won't help either.
Mark Ransom
I believe the point here is to avoid duplicating the _bodies_ of `MyFunctionName`.
Pavel Minaev
Pavel: reread the first paragraph.
Roger Pate
A: 

yes its possible, this is basically what std::string and std::wstring do anyway as they are actually typedefs of std::basic_string<charT,traits,alloc>.

jk
In what parallel universe did `std::string` become a function? ;)
Georg Fritzsche
`std::string` has a lot of member functions which are seemingly "widechar-neutral".
Pavel Minaev
+4  A: 

Roger Pate is entire correct about the interface. You shouldn't bother with A and W suffixes. However, this still leaves the problem of implementation. As you supected, templates are the correct solution. And since you don't need the different names, you can leave out the typedefs. You would just have

template <typename TSTRING> void MyFunctionName (TSTRING const&);

MSalters
The only thing here is that I think it chould be `typename TCHAR` rather than `typename TSTRING`.
Pavel Minaev