Question

That's the only thing I can think of. The thing is sentient.

I have a struct as follows:

struct NumPair
{
    wchar_t *pFirst, *pSecond;
    int count;

with ctor, copy assignment and construction as

NumPair( wchar_t *pfirst, wchar_t *psecond, int count = 0)
NumPair( const NumPair& np )
NumPair& operator=( const NumPair& np )

This is an extension of my last problem in which I was asking for a way to sort a list of characters pointers with them containing special (german) characters such as ü, ä, ö.

The solution seems to be using wide character types, but the compiler is throwing over a hundred errors of conversion for some reason.

Sample input:

// dict_ is a container of NumPairs.
dict_.push_back( NumPair ( "anfangen", "to begin, to start" ) );

The compiler is complaining that it cannot convert a const char * to a wchar_t. Fine enough, I change the push_back to say

dict_.push_back( NumPair ( wchar_t("anfangen"), wchar_t("to begin, to start") ) );

Compiler error: Cannot find a NumPair ctor, that accepts all arguments.

What. The. Hell. I tried a full rebuild, thinking my VSC++10 is mucking up. Nope, guess not.

What am I doing wrong?

CODE

The ctor, assignment and copy construction are all deep copies of the wchar_t pointers like below.

wchar.h is included.

NumPair( wchar_t *pfirst, wchar_t *psecond, int count = 0)
    : count(count)
{
    size_t s1, s2;
    s1 = wcslen(pfirst);
    s2 = wcslen(psecond);
    pFirst  = new wchar_t[s1];
    pSecond = new wchar_t[s2];
    wcscpy(pFirst, pfirst);
    wcscpy(pSecond, psecond);
}
Was it helpful?

Solution

Strings have to begin with an L to be wide-character string literals, e.g. L"abcdefghijk", which is of type const wchar_t*. Without the L it's a narrow-character string, of type const char*, so the error is correct; attempting to cast a const char* to wchar_t* won't work, because you're just changing the type of the pointer and losing the const qualifier (it does nothing to the pointed-to data). Also, your second example is creating wchar_t objects from const char* pointers, which probably isn't what you want either - you want pointers, not just a single wchar_t object.

It's not sentient, you're just not clear what you're doing :)

OTHER TIPS

There are two main issues.

First, a string literal of wchar_t is written like L"blah blah" (note the L).

Second, const correctness: declare your formal argument like wchar_t const* pFirst. This allows using a literal directly as actual argument. Or any const string.

Cheers & hth.,

Try

dict_.push_back( NumPair ( L"anfangen", L"to begin, to start" ) ); 

The L denotes it's a unicode (wchar) string.

A "string in quotes" is an array of chars. You can't convert that to an array of wchar_t without copying. But with an L in front, a L"string in quotes" is literal which gives you an array of wchar_ts instead. You want that L in front of your literals:

NumPair( L"anfangen", L"to begin, to start" )

To create strings of wchar_t characters, use the L prefix on the literals.

dict_.push_back( NumPair ( L"anfangen", L"to begin, to start" ) ); 

P.S. If you don't create your object strings one larger than the string length to accomodate the zero terminator, you'll be in trouble. You might consider using std::wstring.

Most likely, just forget about doing it the way you are with pointers and use std::wstring, the built-in string class that takes wide character strings.

If you are always going to use pointers to literals then you should use const wchar_t * pointers.

Note that your struct will still be assignable as the members are not constant pointers, they are pointers to immutable data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top