簡體   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