【问题标题】:Should I use _T or _TEXT on C++ string literals?我应该在 C++ 字符串文字上使用 _T 还是 _TEXT ?
【发布时间】:2011-01-05 16:26:01
【问题描述】:

例如:

// 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 是为了清楚起见。这仅仅是程序员的主观偏好还是比这更具技术性?例如,如果我使用其中一个,我的代码会不会针对特定系统或某些旧版本的头文件编译?

【问题讨论】:

  • 这上面应该有一个visual-c++标签,还是_T()在实现中很常见?
  • Windows 头文件中还有一个TEXT 宏(没有前导下划线)。第四种(也是最短的)替代方法是在任何地方使用“宽”字符串 (L"…") — Windows 98/Me 不再广泛使用。

标签: c++ winapi backwards-compatibility literals


【解决方案1】:

我从未见过有人用_TEXT() 代替_T()

【讨论】:

    【解决方案2】:

    提交 Unicode 并使用 L"My String Literal"

    【讨论】:

    • 如果您致力于 MS,那太好了。使用他们所有花哨的宏和语言扩展。使用_T 意味着somebody 在转换到任何其他平台 时将不得不更改您的代码。只有不成功的软件永远不会移植...
    • 如果您正在编写 代码(即使在旧代码库中),绝对没有理由不总是使用L""。另一个习惯是显式调用宽函数,即使用 MessageBoxW 而不是 MessageBox 等 - 它确保代码无论如何编译都能正常工作。请记住,所有不支持开箱即用的 Unicode API 的 MS 操作系统都已不受支持。此外,非 Unicode 版本在任何 NT 操作系统上的效率都较低。不要忘记 MSLU / UnicoWS.dll 用于那些需要支持 9x 的情况,这样即使在那里你也可以继续使用 Unicode。
    • 我想说他已经绑定了Win32,如果要移植代码当然要解决这个问题,但是文本宏是一个ADDITIONAL的东西来处理。仅仅因为一个方面不可移植并不意味着所有的赌注都没有。
    • @STingRaySC:_T 根本不会将您与 Microsoft 联系起来。 #define _T(x) L##x 你就完成了。
    • 如果我们要将当前的代码库移植到 Linux,_T() 将是我们最不担心的问题之一。编写一个替换宏是一件很容易的事。从 MFC 转换到其他东西需要更多时间。
    【解决方案3】:

    Here 是来自知名且受人尊敬的来源的有趣读物。

    同样,_TEXT 宏将映射到 L"..." 而不是 "..."。

    _T 呢?好吧,我不知道那个。也许只是为了节省一些打字时间。

    【讨论】:

    • 您遗漏了一个关键位: _TEXT("hello") == L"hello" 仅当定义了 UNICODE 时。是的,_T("hello") 只是一个缩写。
    • UNICODE_UNICODE 都应始终定义,除非您计划穿越到九十年代。
    【解决方案4】:

    两者都没有。根据我的经验,有两种基本类型的字符串文字,一种是不变的,另一种是在您的代码本地化时需要翻译的。

    在编写代码时区分两者非常重要,这样您就不必稍后再找出哪个是哪个。

    所以我将_UT() 用于不可翻译的字符串,将ZZT()(或其他易于搜索的内容)用于需要翻译的字符串。代码中_T()_TEXT() 的实例是尚未正确分类的字符串文字的证据。

    _UTZZT 都是#defined to _TEXT

    【讨论】:

    • 你应该有一个比搜索/替换更好的字符串本地化系统。
    • 我喜欢这个主意。我很难弄清楚哪些字符串显示给用户(因此应该翻译)以及哪些字符串进入日志文件(不应该)。
    • @Mark:是什么让你认为我没有?
    • 怀念ZZT的日子……我跑题了。
    【解决方案5】:

    SDK 的简单 grep 告诉我们答案是没关系——它们是相同的。他们都变成了__T(x)

    C:\...\Visual Studio 8\VC>findstr /spin /c:"#define _T(" *.h crt\src\tchar.h:2439:#define _T(x) __T(x) 包括\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) 包括\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 包括\tchar.h:210:#define __T(x) L ## x 包括\tchar.h:858:#define __T(x) x

    但是,技术上,对于 C++,您应该使用 TEXT() 而不是 _TEXT(),但它(最终)也会扩展为相同的东西。

    【讨论】:

    • 有趣。它们不仅相同,而且在同一个标​​头中定义。我错误地认为 _TEXT 是 Win32 而 _T 是 ATL。
    • @Max:奇怪的是,它们也在 MAPINls.h 和 MAPIWin.h 中定义,但我不确定为什么,为了简单起见,我将它们排除在上述结果之外。但是,是的,它们不是 ATL 的东西,而是 Win32 的东西。 ATL 文档可能会使用它,因为他们更喜欢它? ATL 就是为了节省您的打字时间,对吗? :)
    • TEXT_TEXT 如果定义了 UNICODE 但未定义 _UNICODE 则不同(它们分别对应)
    【解决方案6】:

    来自Raymond Chen

    TEXT 与 _TEXT 与 _T,以及 UNICODE 与 _UNICODE

    没有 下划线影响字符集 Windows 头文件视为 默认。所以如果你定义 UNICODE, 然后 GetWindowText 将映射到 GetWindowTextW 而不是 例如,GetWindowTextA。 同样,TEXT 宏将映射到 L“...”而不是“...”。

    带下划线的版本 影响 C 运行时的字符集 头文件被视为默认值。因此,如果 你定义 _UNICODE,然后 _tcslen 将 映射到 wcslen 而不是 strlen,对于 例子。同样,_TEXT 宏 将映射到 L"..." 而不是 "..."。

    _T 呢?好吧,我不知道 关于那个。也许只是为了 为某人节省一些打字时间。

    短版:_T()是懒人的_TEXT()

    注意:您在编写时需要了解源代码文本编辑器使用的代码页:

    _TEXT("Some string containing Çontaining");
    TEXT("€xtended characters.");
    

    编译器看到的字节取决于编辑器的代码页。

    【讨论】:

      【解决方案7】:

      这些宏是应用程序可能实际上想要同时编译 unicode 和 ANSI 版本的时代的产物。

      今天没有理由这样做 - 这都是退化的。微软一直坚持永远支持所有可能的配置,但你不是。如果您没有同时编译为 ANSI 和 Unicode(老实说,没有人编译),请使用 L"text"。

      是的,如果现在还不清楚:_T == _TEXT

      【讨论】:

        【解决方案8】:

        两者都不使用,也请不要使用 L"..." 废话。 对所有字符串使用 UTF-8,并在传递给 Microsoft API 之前对其进行转换。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2011-02-08
        • 2022-10-14
        • 1970-01-01
        • 2014-05-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多