我发布了a similar question yesterday ,该网站建议发布一个新问题并提供更好的解释。
有两个宏:
#define COMPANY L"Test Company"
#define PRODUCT COMPANY L" in Canada"
产品的结果将是“加拿大测试公司”。
现在,我们有以下要求:
- 将 COMPANY 设置为“动态”字符串,以调用函数返回公司名称,例如 . #define COMPANY getCompanyName()
- 我们不允许更改其他代码来引用 COMPANY,例如 #define PRODUCT COMPANY L"in Canada",因为代码中有太多宏
更改的问题: Product 的结果将是“Test Company”,丢失了“in Canada”字面部分。
这是代码:
#include <stdio.h>
#include <tchar.h>
const wchar_t* getCompanyName() { return L"Test Company";};
#define COMPANY getCompanyName();
#define PRODUCT COMPANY L" in Canada"
int _tmain(int argc, _TCHAR* argv[])
{
const wchar_t * company = COMPANY; // get Test Company
const wchar_t * product = PRODUCT; // get Test Company in Canada
wprintf(company);
wprintf(product);
return 0;
}
最佳答案
这是一个令人讨厌的黑客行为,但实际上是可能的。将 COMPANY
定义为一个表达式,该表达式以文字开头,以文字结尾,并且可以隐式转换为 const wchar_t *
:
#define COMPANY L"" + getCompanyName() + L""
当然,getCompanyName()
一定不能返回const wchar_t *
,因为operator+
没有定义两个指针,它适用于地址而不是字符串。
您基本上需要 as std::wstring
,但您可能需要将其转换为 const wchar_t *
,其中 std::wstring
> 不是。所以你必须定义你自己的类:
struct AutoConvertibleString {
std::string s;
AutoConvertibleString(const std::string &s) : s(s) {}
// C++ optimization for move:
// AutoConvertibleString(std::string s) : s(std::move(s)) {}
operator const wchar_t *() { return s.c_str(); }
};
AutoConvertibleString operator+(const wchar_t *l, const AutoConvertibleString &r) {
return (l + r.s).c_str();
}
AutoConvertibleString operator+(const AutoConvertibleString &l, const wchar_t *r) {
return (l.s + r).c_str();
}
// Ok, the operator+s could be optimized to use move for temporaries too...
AutoConvertibleString getCompanyName() { /* ... whatever ... */ }
这是一个丑陋的黑客行为。将它们全部转换为函数确实会更好。但它应该可以工作。
关于c++ - 如何在 C 或 C++ 宏中将函数用作文字字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19222947/