2

昨天发布了一个类似的问题,该网站建议发布一个具有更好解释的新问题。

有两个宏:

#define COMPANY L"Test Company"
#define PRODUCT COMPANY L" in Canada"

PRODUCT 的结果将是“Test Company in Canada”。

现在,我们有以下要求:

  1. 将 COMPANY 设为“动态”字符串,以调用函数返回公司名称,例如 . #define 公司 getCompanyName()
  2. 我们不允许更改其他代码以引用 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;
} 
4

2 回答 2

2

PRODUCT的宏在

getCompanyName(); L" in Canada"

所以

const wchar_t * product = getCompanyName(); L" in Canada";
wprintf(product);

印刷

Test Company

正如预期的那样。

在 C++ 中,我们倾向于:

  • 避免使用宏(改用内联函数)
  • 避免裸指针(首选 STL 工具)

因此,在 C++ 中,我们更喜欢:

inline const std::wstring getCompanyName() { return L"Test Company";}
inline const std::wstring PRODUCT() { return getCompanyName() + L" in Canada";}
于 2013-10-07T11:01:07.970 回答
2

这是一个讨厌的黑客,但它实际上是可能的。定义COMPANY为以文字开头、以文字结尾且可以隐式转换为 a 的表达式const wchar_t *

#define COMPANY L"" + getCompanyName() + L""

当然getCompanyName() 不能return 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 ... */ }

这是一个丑陋的黑客。将它们全部转换为函数会更好。但它应该工作。

于 2013-10-07T12:10:50.970 回答