Reputation: 4274
Sometimes there is need to create string literals with the same value for both char *
and wchar_t *
types (e.g. when developing in Windows). A simply way is to write the definition twice:
const char *my_string = "Hello World";
const wchar_t *my_wide_string = L"Hello World";
The problem is that if we need to change the string, instead of just changing one place, both lines need to be updated, often lead to typos and bugs. Ideally the literal should only appear once and both variables are populated from it.
We could define the char
variable and convert it to the wchar_t
version at runtime. However, it is better to avoid the runtime cost since the literal is already available at compile time.
I thought to use the token-pasting operator, but can't make it work because it only accepts another string literal:
#define my_string "Hello World"
#define make_wide(str) L##str
#define my_wide_string make_wide(my_string) // expand to Lmy_string instead of L"Hello World"
I'm not sure if one can use constexpr
to make it work?
Upvotes: 1
Views: 1305
Reputation: 42042
Since you're on Windows you can use _STR2WSTR
in crtdefs.h which gets included when you #include <windows.h>
. There are also __FILEW__
and __FUNCTIONW__
made from the normal string variant as examples
/* error reporting helpers */
#define __STR2WSTR(str) L##str
#define _STR2WSTR(str) __STR2WSTR(str)
#define __FILEW__ _STR2WSTR(__FILE__)
#define __FUNCTIONW__ _STR2WSTR(__FUNCTION__)
Update:
Later CRT versions have change that to _CRT_WIDE
#define _CRT_WIDE_(s) L ## s
#define _CRT_WIDE(s) _CRT_WIDE_(s)
Upvotes: 1
Reputation: 224596
You just need another macro so the argument of the macro is expanded before pasting:
#include <wchar.h>
#define my_string "Hello World"
#define WidenHelper(x) L##x
#define Widen(x) WidenHelper(x)
const char *plain = my_string;
const wchar_t *wide = Widen(my_string);
Upvotes: 3
Reputation: 11178
It's unlikely that you want both versions in a proper design. Anyway, the two types (char
and wchar_t
) are not compatible (8/16 bits) so you can't do it at the compile level.
Design a class that uses wchar_t and converts to char only when necessary. You use WideCharToMultiByte for this.
Design your entire application to only use wide characters and only use UTF-8 forms when serializing.
Upvotes: 0