A simple approach, which will work with all C++ standards, would be
#include <string>
#include <windows.h> // or whatever header you're using that specifies TCHAR
int main()
{
std::string test("Hello"); // string to be converted
// first, if you need a const TCHAR *
std::basic_string<TCHAR> converted(test.begin(), test.end());
const TCHAR *tchar = converted.c_str();
// use tchar as it is in the required form (const)
// second, if you need a TCHAR * (not const)
std::vector<TCHAR> converted2(test.begin(), test.end());
TCHAR *tchar2 = &converted2[0];
// use tchar2 as it is of the required form (non-const).
}
std::basic_string
does not provide a means in all C++ standards to obtain a non-const
pointer to its data, but std::vector
does. (Assuming you don't use an explicit conversion to introduce or remove const
ness).
In C++17 and later, things are simpler: the basic_string::data()
has both a const
and non-const
overload, which wasn't the case before the 2017 standard. Before C++11, the data in a basic_string
was not guaranteed to be contiguous by the standard (even if implementations typically implemented things that way) but c_str()
did provide the address of the first character of a contiguous array. The net effect is that, in C++17 and later, appropriate overloads of basic_string::data()
or basic_string::c_str()
can be used, without a need for cast to change const
ness, and without resorting to a vector
(which has been guaranteed to have contiguous elements in all C++ standards).
Points to note in both cases
- The pointers (
tchar
and tchar2
) are invalidated if their respective containers (converted
or converted2
) are resized or if they cease to exist. For example, don't use the data pointed to by tchar
if converted
has passed out of scope, since data tchar
points at will no longer exist.
- It is simply undefined behaviour to use the pointers to run past the end (no magical resizing when using the pointers).