1

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);
}
IAE
  • 2,213
  • 13
  • 37
  • 71
  • You failed when you tried to manage more than one resource at a time, namely a string. We already solved this problem, it's `std::wstring`. – GManNickG Nov 01 '10 at 19:21
  • 1
    You need to add one more character for the null terminator and also handle destruction. Technically your code is also not exception safe if the second new fails as the first one will never get deleted (destructor won't be called). Best to use std::wstring. – CashCow Nov 02 '10 at 10:01

6 Answers6

5

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.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
4

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 :)

AshleysBrain
  • 22,335
  • 15
  • 88
  • 124
3

Try

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

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

user470379
  • 4,879
  • 16
  • 21
3

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" )
aschepler
  • 70,891
  • 9
  • 107
  • 161
2

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.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
2

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.

CashCow
  • 30,981
  • 5
  • 61
  • 92