【问题标题】:How can I convert combined literal constant into wchar in compile time?如何在编译时将组合文字常量转换为 wchar?
【发布时间】:2016-06-30 12:41:02
【问题描述】:

我在预处理器宏中定义了一个组合文字常量,例如

#define A "1"
#define B "3"
#define VERSION A "." B

最终我想稍后通过使用 _T 宏将其转换为 wchar_t *,例如:

TCHAR * version = _T(VERSION);

但是它无法使用 Visual Studio 2013 运行时编译并出现以下错误:

连接不匹配的字符串

它似乎在较新的版本中得到了修复,上面的代码使用 VS2015 运行时编译没有问题。

任何想法如何使它与 VS2013 运行时一起工作?

【问题讨论】:

  • 如果2015年能用,为什么不升级呢?社区版是免费的。每个版本确实改进了编译器。以后的修复不适用于以前的版本
  • 检查C++ String Literals页面上指定宽字符串文字的正确方法,即使用L前缀。如果您明确使用wchar_t,则没有理由使用_T

标签: c++ visual-studio-2013


【解决方案1】:

它们都需要宽或窄,试试:

#define A L"1"
#define B L"3"
#define VERSION A L"." B

const wchar_t * version = VERSION;

或者

#define A "1"
#define B "3"
#define VERSION A "." B

const char * version = VERSION;

编辑:这个回答了评论

#define A "1"
#define B "3"
#define VERSION A "." B

#define EXPAND(x) _T(##x)
#define TO_WIDE(x) (EXPAND(x))

const wchar_t * version = TO_WIDE(VERSION);

【讨论】:

  • 假设我在另一个我无法修改的头文件中有这些定义。我需要将该值用作 wchar_t。
  • #define WIDE_VERSION _T(A) L"。" _T(B)
  • 感谢您的回答。它看起来是目前最好的解决方案。但是我想知道是否有针对此问题的更通用的解决方案。
  • 除了使用宏重新定义标题或在运行时将字符串从窄转换为宽之外,您无能为力:编辑:通过令牌粘贴找到了一种方法,编辑:没关系只返回“版本”而不是真正的字符串:(
  • 看来VS2013运行时还是会产生编译错误。
【解决方案2】:

其实我并没有找到完美的解决方案。但是我发现了如何修改 VERSION 宏的创建,以便能够简单地将 _T 宏应用于它。代码如下:

#define MAJOR 3
#define MINOR 1

#define DOT .

#define __STR2(x) #x
#define __STR(x) __STR2(x)

#define _CONCAT3(s1, s2, s3) s1 ## s2 ## s3
#define CONCAT3(s1, s2, s3) _CONCAT3(s1, s2, s3)

#define VERSION_STR __STR(CONCAT3(MAJOR, DOT, MINOR))

然后

TCHAR * version = _T(VERSION);

工作正常。

【讨论】:

  • 为什么不升级到2015呢?社区版是免费的。 为什么继续支持已经修复的错误?
  • 首先,您正在尝试backport 代码。在这种情况下就是那么简单——使用正确的编译器版本而不是试图破解它。正如其他人指出的那样,它甚至可以在 2013 年进行适当的更新。其次,您尝试使用宏而不是 wstring 类型,甚至使用了错误的文字(即您错过了L)。一般来说,这不是一个好主意。
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 2013-11-08
  • 2014-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多