String to char*

c_str() will behave exactly the same way! These classes all return pointers to memory that’s owned by the string object, so it can’t be used beyond the lifetime of the string.

Why do you need to pass a char* anyway? Just return a string, and let the caller worry about turning it into a char* when it actually needs to do so…

well that’s what I’m saying, that c_str() behaves differently. c_str returns the actually string memory pointer owned by the string object, and I can pass it through functions (and return pointers).
Since toUtf8 creates a copy instead of returning a pointer to it’s internal text, the copy gets deleted as soon as I exit my function that’s calling toUtf8.

I just chose to pass a char*, I could also return a string&. Same problem though.

er… don’t think so! You might be lucky enough that your program doesn’t crash, but you’re referencing deleted memory. The std::string class is exactly the same as mine - once you delete or modify it, that c_str() pointer is invalid.

Yeah, so return an actual String, not a reference or pointer! That’s the whole point of copy-by-value semantics (!)

not sure if we’re talking about the same thing.
The windows implementation simply returns a pointer, there’s no copying going on at all.
const _Elem *c_str() const
{ // return pointer to null-terminated nonmutable array
return (_Myptr());

that pointer is valid till the actual string object is destroyed, no earlier.
I’ll try returning an actual string. I prefer not having to make unnecessary copies though.

You realise that String objects have reference counted internal data? You’re not copying anything by returning a String object, you’re just giving the internal data life-support. If you really wanted to return a normal C string, you would have to make a copy so that you have control over its lifetime. The String class takes care of that for you - you really are worrying about nothing, and making more work for yourself!

[quote]not sure if we’re talking about the same thing.
The windows implementation simply returns a pointer, there’s no copying going on at all.[/quote]

You could do the same thing with a juce String by casting it to a const juce_wchar* rather than UTF8, but that’s not the point.

Like haydxn said, the String class is reference-counted and fast, but even if it wasn’t, any decent compiler will optimise-out the copy of the return value anyway - there’s a temporary string already there on the stack, so the compiler can just leave it in place for the caller to use when the function returns, requiring zero overhead. If you cast it to a pointer, that’ll require some overhead, even if it’s just a few instructions.

Did toCString() get removed since this posting was made? I don’t see it anywhere.

I’m attempting to call a library that uses a lot of const std::string & as parameters throughout the API, but I have a bunch of juce::String objects in my code. Trying to pass in my juce::String objects returns the following compiler error:

[color=#BF0000]error: invalid initialization of reference of type ‘const string& {aka const std::basic_string&}’ from expression of type ‘juce::String’[/color]

So after a bit of searching, I found getCharPointer() which I figured would work since std::string can be constructed from a char*. But,

[color=#BF0000]error: invalid initialization of reference of type ‘const string& {aka const std::basic_string&}’ from expression of type ‘const CharPointerType {aka const juce::CharPointer_UTF8}’

Looking up CharPointer_UTF8, I see it is a class, not a typedef. But it does have an operator char*, so now I’m stuck doing this with all my parameters:

What I’d rather do if possible is:

If that’s not possible, my next choice would be something along these lines:

foo( a.toCString(), b.toCString(), c.toCString() ); foo( a.c_str(), b.c_str(), c.c_str() ); foo( a.str(), b.str(), c.str() );

This is what led me to this post on the forum where Jules referenced toCString()…which I cannot find anywhere.

Any chance we can make conversion easier/automatic between juce::String and std::string?


Yes, toCString was a bad idea, and was removed long ago. If anything, you probably want toUTF8(). getCharPointer() is the wrong thing to use, although in practical terms it’ll actually do the same job as toUTF8(). Personally, I’d write foobar (myString.toUTF8().getAddress()).

I’ve been reluctant to add implicit casts because std::string is agnostic about the encoding that it contains. If the thing that uses the string is expecting an ascii C-string and gets a utf8 one, it could cause unexpected results, which is why I’d rather force people to write toUTF8(). I also didn’t want the juce headers to include std::string, although as the c++ standard has become more pervasive over the years, I wouldn’t really object to that any more.

I was researching using libpqxx tonight, a C++ database API to PostgreSQL, and everywhere I had Juce strings, I had to pass them into libpqxx using [color=#0000BF]str.toUTF8().getAddress()[/color]. Had to look up this thread cause I couldn’t remember how to convert from JUCE::String to std::string or char*.

Is this something you’d add, Jules? Especially for fools like me who are always combining non-JUCE C/C++ libraries, it would be nice to have a simpler/shorter method to call, or a conversion operator.

I guess I could go as far as adding “toRawUTF8”. But a conversion operator: no, absolutely not - to allow implicit casts to char* would be a very bad move.

Actually, I was thinking a conversion operator to std::string. If people need a char* then it is very common practise to call c_str() on a std::string.

Ah, a cast to std::string is a different question. I’ve been pondering that recently anyway.

My gripe with std::string is that it’s encoding-agnostic, so any juce strings that get cast into a utf-8 std::string could easily get passed to functions that aren’t expecting utf-8. But I guess that’s just a problem with std::string in general, so not something I should try to fix.

Yes please. This was also a concern here.

[quote=“Salvator”]Yes please. This was also a concern here.

I already added this a few days ago.

Oh, baby!

I can remove all that code I have from converting between juce::String and std::string… aces!