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

Zak
  • 12,213
  • 21
  • 59
  • 105
yms
  • 10,361
  • 3
  • 38
  • 68
  • 7
    SO is a question site, not a bug tracker, so the title should be a question, not a complaint ;-) – Steve Jessop Sep 21 '12 at 15:52
  • 2
    [String::Begin](http://msdn.microsoft.com/en-us/library/windows/apps/hh825849.aspx), [String::End](http://msdn.microsoft.com/en-us/library/windows/apps/hh825864.aspx), What more do you need? – Benjamin Lindley Sep 21 '12 at 15:56
  • 2
    The string has iterators, can't you simply use standard algorithms? – Etienne de Martel Sep 21 '12 at 15:58
  • 3
    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. – R. Martinho Fernandes Sep 21 '12 at 16:01
  • 1
    @R. Martinho Fernandes that makes more sense! thanks! – yms Sep 21 '12 at 16:02
  • @yms Hmm, I may have been misled by the documentation here http://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: http://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. – R. Martinho Fernandes Sep 21 '12 at 16:21
  • 3
    Nevermind that, seems like it's a documentation bug (https://twitter.com/JamesMcNellis/status/249183128097259522). It is really immutable. – R. Martinho Fernandes Sep 21 '12 at 16:31
  • @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.) – IInspectable Jun 04 '16 at 18:46
  • @IInspectable what problem does it solve that `std::string` doesn't? – Mark Ransom Jun 05 '16 at 01:26
  • 1
    @MarkRansom: A standardized ABI, for starters. And being projectable into a language that doesn't support inheritance, like JavaScript. – IInspectable Jun 05 '16 at 09:23

2 Answers2

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

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Hi. Thanks for this answer. Would you mind taking a look at [this question](http://stackoverflow.com/questions/12581714/why-my-c-cx-unit-test-does-not-fail)? It feels like a found a bug in the c++ test framework... – yms Sep 25 '12 at 14:24
  • @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](http://stackoverflow.com/questions/12533883/platformstring-is-kind-of-useless/12534823#comment16958615_12534823). – James McNellis Sep 25 '12 at 14:51
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).

ollb
  • 1,453
  • 1
  • 11
  • 17
  • 2
    `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. – James McNellis Sep 21 '12 at 16:59