Currently, sf::String::toUtf8 returns a std::basic_string<Uint8> object.
I think It would be better if toUtf8 returned a std::string, because this method isn't very useful: you can't do much with these std::basic_string<> objects, and you need to convert them if you want to do very basic things such as:
- display them with std::cout
- write them in a file
- use them in a 3rd party library...
Doing any of these things requires a conversion which could be avoided:
std::basic_string<sf::Uint8> tmp = sfString.toUtf8();
std::string utf8(tmp.begin(), tmp.end());
So, why not returning standard, more convenient objects?
Same remark for toUtf16 / std::wstring.
-display them with std::cout
-write them in a file
-use them in a 3rd party library...
Well, you can print them in any basic_ostream object since there is a corresponding << op:
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);
So using cout or fstream is not a problem.
Regarding 3rd party lib, I think it isn't an argument since anybody can find a 3rd party lib that is not compatible.
Having said that, with c++11 we have std::u16string and std::u32string so it might be a good idea to use them (with std::string for utf8) when we switch to c++11. Of course, we might change more than just the types.
So using cout or fstream is not a problem.
It is, the following code doesn't compile:
#include <SFML/System.hpp>
#include <iostream>
int main()
{
sf::String str("sfml string");
std::cout << str.toUtf8() << std::endl;
}
(gcc 4.7.2)
Regarding 3rd party lib, I think it isn't an argument since anybody can find a 3rd party lib that is not compatible.
But std objects offer a common ground so different pieces of code can work together, especially for something as common as strings. You can always find a workaround, but I don't see the point of using basic_string<Uint8> where there's a standard, more convenient alternative with no drawback (AFAIK).
with c++11 we have std::u16string and std::u32string so it might be a good idea to use them (with std::string for utf8) when we switch to c++11.
That would be very nice indeed, but I believe we'll stick to c++03 for still a little while :)
Error message with -std=c++11:
string_utf8.cpp: In function ‘int main()’:
string_utf8.cpp:7:26: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
In file included from /usr/local/include/SFML/System/Err.hpp:32:0,
from /usr/local/include/SFML/System.hpp:34,
from string_utf8.cpp:1:
/usr/include/c++/4.7/ostream:600:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::basic_string<unsigned char>]’
Anyway, changing the return type now (for 2.x I mean) is not possible since it would break some code.
Ha, I didn't know SFML team was this strict about API breaks. Too bad then.
In the meantime, use `toAnsiString` (if I'm not mistaken it should do the same thing)
This one discards non-ANSI characters.