Должен ли я использовать _T или _TEXT для строковых литералов C ++?
-
20-09-2019 - |
Вопрос
Например:
// This will become either SomeMethodA or SomeMethodW,
// depending on whether _UNICODE is defined.
SomeMethod( _T( "My String Literal" ) );
// Becomes either AnotherMethodA or AnotherMethodW.
AnotherMethod( _TEXT( "My Text" ) );
Я видел и то, и другое._T, по-видимому, для краткости, а _TEXT - для ясности.Является ли это просто субъективным предпочтением программиста или оно более техническое?Например, если я использую одно поверх другого, не будет ли мой код компилироваться для определенной системы или какой-нибудь более старой версии заголовочного файла?
Решение
Простой grep SDK показывает нам, что ответ таков: это не имеет значения — они одинаковые.Они оба превращаются в __T(x)
.
C:\...\Visual Studio 8\VC>findstr /spin /c:"#define _T(" *.h crt\src\tchar.h:2439:#define _T(x) __T(x) include\tchar.h:2390:#define _T(x) __T(x) C:\...\Visual Studio 8\VC>findstr /spin /c:"#define _TEXT(" *.h crt\src\tchar.h:2440:#define _TEXT(x) __T(x) include\tchar.h:2391:#define _TEXT(x) __T(x)
И для полноты:
C:\...\Visual Studio 8\VC>findstr /spin /c:"#define __T(" *.h crt\src\tchar.h:210:#define __T(x) L ## x crt\src\tchar.h:889:#define __T(x) x include\tchar.h:210:#define __T(x) L ## x include\tchar.h:858:#define __T(x) x
Однако, технически, для C++ вы должны использовать TEXT()
вместо _TEXT()
, но (в конце концов) расширяется до того же самого.
Другие советы
Примите Unicode и просто используйте L"My String Literal"
.
От Рэймонд Чен:
ТЕКСТ против_ТЕКСТ против_T, и UNICODE против_УНИКАЛЬНЫЙ КОД
Простые версии без символа подчеркивания влияют на набор символов заголовочные файлы Windows обрабатываются как по умолчанию.Итак, если вы определяете UNICODE, тогда GetWindowText будет сопоставляться с GetWindowTextW вместо GetWindowTextA, например.Аналогично, ТЕКСТОВЫЙ макрос будет отображаться на L"..." вместо "...".
Версии с подчеркиванием влияют на набор символов, используемый средой выполнения C заголовочные файлы обрабатываются по умолчанию.Итак, если вы определяете _UNICODE, то _tcslen будет сопоставляться с wcslen вместо strlen, например.Аналогично, макрос _TEXT будет отображаться на L"..." вместо "...".
А как насчет _T?Ладно, я не знаю насчет этого.Может быть, это было просто для того, чтобы сэкономить кому-то время на наборе текста.
Сокращенная версия: _T()
это работа ленивого человека _TEXT()
Примечание:Вы должны быть осведомлены о том, какую кодовую страницу использует ваш текстовый редактор исходного кода при написании:
_TEXT("Some string containing Çontaining");
TEXT("€xtended characters.");
Байты, которые видит компилятор, зависят от кодовой страницы вашего редактора.
ЗдесьЭто интересное чтение из известного и уважаемого источника.
Аналогично, макрос _TEXT будет отображаться как L"..." вместо "...".
А что насчет _Т?Хорошо, я не знаю об этом.Возможно, это было просто для того, чтобы избавить кого-то от набора текста.
Я никогда не видел, чтобы кто-нибудь использовал _TEXT()
вместо _T()
.
Ни один.По моему опыту, существует два основных типа строковых литералов: инвариантные и те, которые необходимо переводить при локализации кода.
Во время написания кода важно различать эти два понятия, чтобы вам не приходилось возвращаться и выяснять, что есть что позже.
Поэтому я использую _UT()
для непереводимых строк и ZZT()
(или что-то еще, что легко найти) для строк, которые нужно будет перевести.Экземпляры _T()
или _TEXT()
в коде присутствуют строковые литералы, которые еще не были правильно классифицированы.
_UT
и ZZT
оба #определены для _TEXT
Эти макросы являются пережитком тех времен, когда приложение могло действительно захотеть скомпилировать как версию Unicode, так и ANSI.
Сегодня нет смысла это делать – это все рудиментарно.Microsoft навсегда застряла в поддержке всех возможных конфигураций, но вы этого не делаете.Если вы не компилируете одновременно в ANSI и Unicode (а никто этого не делает, давайте будем честными), просто перейдите к L"text".
И да, если сейчас неясно:_Т == _ТЕКСТ
Не используйте ни того, ни другого, а также, пожалуйста, не используйте L"..." чушь.Используйте UTF-8 для всех строк и преобразуйте их непосредственно перед передачей в API Microsoft.