UTF-8, что по определению "немного не char"
Вообще-то UTF-8 - 8 битная кодировка, как раз char.
Другое дело, не всё тут просто. Нельзя сказать, что для преобразования надо использовать только toLocal8Bit(), т.к. неизвестна дальнейшая судьба этой строки в std::string.
Если мы, к примеру, пишем в файл или выводим в stdout/err, то действительно надо делать toLocal8Bit(). Если мы эту строку передаем на сервер, который принимает UTF-8, то соответственно надо использовать toUtf8(). Т.е. надо действовать по ситуации. А при выводе в консоль под виндой надо вообще использовать кодировку CP866, с toLocal8Bit() вас ждет разочарование.
Хорошая практика хранить все строки внутри приложения в QString (которая UTF-16) и преобразовывать только в случае вывода этой строки наружу в нужной кодировке.
Конвертация из std::string в QString:
QString res = QString::fromLocal8Bit(stdStr.data(), stdStr.size());
QString res2 = QString::fromLocal8Bit(stdStr.c_str()); // менее эффективно, т.к. присутствует дополнительный просчет длины строки за кадром
Конвертация из QString в std::string:
QByteArray ba = qStr.toLocal8Bit();
std::string res = std::string(ba.data(), ba.size());
std::string res = std::string(qStr.toLocal8Bit().data()); // менее эффективно, т.к. присутствует дополнительный просчет длины строки за кадром
Добавлю, что в Qt4 QString::fromStdString по умолчанию использует кодировку latin1, которая херит любые не латинские символы. Чтобы изменить кодировку по умолчанию надо воспользоваться QTextCodec::setCodecForCStrings(). В Qt5 - без вариантов используется fromUtf8 для преобразования. Так, что я бы не советовал использовать эту функцию вообще.