C ++ 11 представил необработанные строковые литералы что может быть очень полезно для представления строк в кавычках, литералов с множеством специальных символов, таких как пути к файлам Windows, выражения регулярных выражений и т. д.
std::string path = R"(C:\teamwork\new_project\project1)"; // no tab nor newline!
std::string quoted = R"("quoted string")";
std::string expression = R"([\w]+[ ]+)";
Эти необработанные строковые литералы также можно комбинировать с префиксами кодирования (u8
, u
, U
, или же L
), но если префикс кодирования не указан, имеет ли значение кодировка файла?, давайте предположим, что у меня есть этот код:
auto message = R"(Pick up a card)"; // raw string 1
auto cards = R"()"; // raw string 2
Если я смогу написать и сохранить приведенный выше код, очевидно, что мой исходный код закодирован как Unicode, поэтому мне интересно:
raw string 1
будет ли Unicode буквальным? (хотя он использует только символы ASCII), другими словами, наследует ли необработанная строка кодификацию файла, в котором написано, или компилятор автоматически определяет, что unicode не нужен, независимо от кодировки файла?U
на raw string 2
для того, чтобы рассматривать его как литерал Юникода, или он будет автоматически в Юникоде из-за его содержимого и / или кодировки исходного файла?Спасибо за внимание.
РЕДАКТИРОВАТЬ:
Тестирование приведенного выше кода на ideone.com и распечатка message
а также cards
переменные, это выводит char const*
:
template<typename T> std::string demangle(T t)
{
int status;
char *const name = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
std::string result(name);
free(name);
return result;
}
int main()
{
auto message = R"(Pick up a card)";
auto cards = R"()";
std::cout
<< "message type: " << demangle(message) << '\n'
<< "cards type: " << demangle(cards) << '\n';
return 0;
}
Выход:
message type: char const*
cards type: char const*
что даже более странно, чем я думал, я был уверен, что тип будет wchar_t
(даже без L
префикс).
Да, это важно, даже для компиляции вашего источника. Вам нужно будет использовать somenthing, как -finput-charset=UTF-16
компилировать, если вы используете gcc
(то же самое должно относиться к VS).
Но я, IHMO, есть кое-что более фундаментальное, чтобы принять во внимание в вашем коде. Например, std::string
контейнеры для char
, что составляет 1 байт. Если вы имеете дело, например, с UTF-16, вам потребуется 2 байта, поэтому (несмотря на «ручное преобразование») вам понадобится как минимум wchar_t
(std :: wstring) (или, чтобы быть более безопасным, char16_t
, чтобы быть в безопасности C++11
).
Таким образом, для использования Unicode вам понадобится контейнер для него и среда компиляции, подготовленная для обработки ваших кодифицированных источников Unicode.
Необработанные строковые литералы изменяют способ обработки экранирования, но не меняют способ обработки кодировок. Необработанные строковые литералы по-прежнему преобразуют свое содержимое из исходной кодировки для получения строки в соответствующей кодировке выполнения.
Тип строкового литерала и соответствующая кодировка выполнения полностью определяются префиксом. R
один всегда производит char
Строка в узком исполнении кодировки. Если источником является UTF-16 (а компилятор поддерживает UTF-16 в качестве кодировки источника), то компилятор преобразует содержимое строкового литерала из UTF-16 в кодировку с узким исполнением.