Is Platform::String really so useless?
Asked Answered
M

2

11

I am trying to write a few lines of code in C++/CX in a "Windows Store" (aka Metro Style) application, and I am surprised to see that Platform::String is missing many basic string operations like "replace" or "index of".

I suppose I could use the internal data, pass it to a std:string instance and apply the operations I need, but I would like to know if I am missing some "Platform::* only" way of doing these operations.

Please note this question is about C++/CX, not C#.

Massimiliano answered 21/9, 2012 at 15:49 Comment(10)
SO is a question site, not a bug tracker, so the title should be a question, not a complaint ;-)Epithalamium
String::Begin, String::End, What more do you need?Shane
The string has iterators, can't you simply use standard algorithms?Decay
Platform::String is immutable, so mutating operations like "replace" make no sense. Non-mutating operations can be done just fine by using iterators in the standard algorithms. It doesn't look useless at all to me.Dogmatics
@R. Martinho Fernandes that makes more sense! thanks!Massimiliano
@Massimiliano Hmm, I may have been misled by the documentation here msdn.microsoft.com/en-us/library/windows/apps/hh755812.aspx to believe that the strings are immutable. However, the Begin method returns a non-const pointer: msdn.microsoft.com/en-us/library/windows/apps/hh825849.aspx. It seems you can mutate individual elements of the string but not add or remove any. Weird.Dogmatics
Nevermind that, seems like it's a documentation bug (twitter.com/JamesMcNellis/status/249183128097259522). It is really immutable.Dogmatics
@MarkRansom: What would you propose instead? Or, more to the point, how would you have solved the problem that Platform::String solves? (Note: You cannot use a time machine as part of your solution.)Emaciation
@Emaciation what problem does it solve that std::string doesn't?Whoreson
@MarkRansom: A standardized ABI, for starters. And being projectable into a language that doesn't support inheritance, like JavaScript.Emaciation
G
19

The Windows Runtime string type, HSTRING is immutable and is reference counted.

The Platform::String type in C++/CX is simply a wrapper around the HSTRING type and the handful of operations that it supports (see the functions that start with Windows in the Windows Runtime C++ Functions list).

There are no operations that mutate the string because the string type is immutable (hence why there is no Replace). There are a few non-mutating operations (certainly fewer than C++'s std::wstring).

Platform::String does provide Begin() and End() member functions (and non-member begin() and end() overloads) that return random access iterators into the string (they return pointers, wchar_t const*, and pointers are valid random access iterators). You can use these iterators with any of the C++ Standard Library algorithms that take random access iterators and do not attempt to mutate the underlying sequence. For example, consider using std::find to find the index of the first occurrence of a character.

If you need to mutate a string, use std::wstring or std::vector<wchar_t>. Ideally, consider using the C++ std::wstring as much as possible in your program and only use the C++/CX Platform::String where you need to interoperate with other Windows Runtime components (i.e., across the ABI boundary).

Gibert answered 21/9, 2012 at 16:55 Comment(2)
Hi. Thanks for this answer. Would you mind taking a look at this question? It feels like a found a bug in the c++ test framework...Massimiliano
@yms: That is a good question; I'm not sure of the answer, but I can try to find someone who can answer it. For what it's worth, I've found it useful for unit testing purposes to synchronize all asynchronous operations (using a spin wait, to circumvent the STA-blocking restrictions). It's simple and straightforward to do this; you can see a generic example in my CxxReflect project's unit test code.Gibert
S
11

That is because it isn't intended to be a std::string replacement. From the docs:

The Platform::String Class provides methods for several common string operations, but it's not designed to be a full-featured string class. In your C++ module, use standard C++ string types such as wstring for any significant text processing, and then convert the final result to Platform::String^ before you pass it to or from a public interface.

http://msdn.microsoft.com/en-us/library/windows/apps/hh699879.aspx

So the bottom line is: use std::wstring like you were used to in C++ and only convert to Platform::String when needed.

I think that it is probably better that way, because Platform::String has some pretty confusing semantics (for example nullptr and the empty string are the same thing, so ref new String() == nullptr is true).

Shogun answered 21/9, 2012 at 16:39 Comment(1)
Platform::String has odd semantics, yes, especially with respect to "null." The oddities are largely caused by the fact that the Windows Runtime string type, HSTRING, is a value type (and thus has no "null" value) but the type is reference counted and requires explicit creation and destruction. It is, in a sense, a bit of a mix between a value type and a reference type.Gibert

© 2022 - 2024 — McMap. All rights reserved.