繁体   English   中英

如何在C或C ++宏中将函数用作文字字符串

[英]how to use function as literal string in C or C++ macro

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

有两个宏:

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

PRODUCT的结果将是“加拿大测试公司”。

现在,我们有以下要求:

  1. 使COMPANY为“动态”字符串,以调用函数以返回公司名称,例如。 #define COMPANY getCompanyName()
  2. 我们不允许更改其他代码来引用该公司,例如#define PRODUCT COMPANY L“加拿大”,因为该代码中有很多宏

变更问题: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;
} 

您的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";}

这是一个讨厌的hack,但实际上是可能的。 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 ... */ }

这是一个丑陋的骇客。 将它们全部转换为函数确实更好。 但是应该可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM