我发布了a similar question yesterday,该网站建议发布一个更好解释的新问题。
有两个宏:
#define COMPANY L"Test Company"
#define PRODUCT COMPANY L" in Canada"
PRODUCT的结果将是“加拿大的测试公司”。
现在,我们有以下要求:
变更问题: PRODUCT的结果将是“测试公司”,丢失了“加拿大”字面部分。
以下是代码:
#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;
}
答案 0 :(得分:2)
您PRODUCT
宏扩展为
getCompanyName(); L" in Canada"
所以
const wchar_t * product = getCompanyName(); L" in Canada";
wprintf(product);
打印
Test Company
正如所料。
在C ++中我们倾向于:
所以,在C ++中我们更喜欢:
inline const std::wstring getCompanyName() { return L"Test Company";}
inline const std::wstring PRODUCT() { return getCompanyName() + L" in Canada";}
答案 1 :(得分:2)
这是一个讨厌的黑客,但它实际上是可能的。将COMPANY
定义为以文字开头的表达式,以文字结尾,可以隐式转换为const wchar_t *
:
#define COMPANY L"" + getCompanyName() + L""
当然getCompanyName()
一定不能返回const wchar_t *
,因为operator+
没有为两个指针定义,而且无论如何它都适用于地址而不是字符串。
您基本上需要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 ... */ }
这是一个丑陋的黑客。将所有这些转换为函数真的会更好。但它应该有用。