C++ 如何在C或C+中使用函数作为文本字符串+;宏

C++ 如何在C或C+中使用函数作为文本字符串+;宏,c++,macros,C++,Macros,我发了一个帖子,网站建议我发一个新的问题,并给出更好的解释 有两个宏: #define COMPANY L"Test Company" #define PRODUCT COMPANY L" in Canada" 产品结果将是“加拿大测试公司” 现在,我们有以下要求: 将公司设置为“动态”字符串,以调用函数返回公司名称,例如#定义公司getCompanyName() 我们不允许更改其他代码以引用该公司,例如“在加拿大”定义产品公司L,因为代码中有太多宏 变化的问题: 产品的结果将是“测试公司”,

我发了一个帖子,网站建议我发一个新的问题,并给出更好的解释

有两个宏:

#define COMPANY L"Test Company"
#define PRODUCT COMPANY L" in Canada"
产品结果将是“加拿大测试公司”

现在,我们有以下要求:

  • 将公司设置为“动态”字符串,以调用函数返回公司名称,例如#定义公司getCompanyName()
  • 我们不允许更改其他代码以引用该公司,例如“在加拿大”定义产品公司L,因为代码中有太多宏
  • 变化的问题: 产品的结果将是“测试公司”,失去了“在加拿大”的文字部分

    代码如下:

    #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;
    } 
    
    #包括
    #包括
    const wchar_t*getCompanyName(){返回L“测试公司”;};
    #定义公司getCompanyName();
    #定义产品公司L“在加拿大”
    int _tmain(int argc,_TCHAR*argv[]
    {
    const wchar\u t*company=company;//获取测试公司
    const wchar_t*product=product;//在加拿大获得测试公司
    wprintf(公司);
    WPRITF(产品);
    返回0;
    } 
    
    您可以在

    getCompanyName(); L" in Canada"
    
    所以

    印刷品

    测试公司

    正如所料

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

    • 避免使用宏(改用内联函数)
    • 避免裸指针(首选STL工具)
    < >,在C++中,我们更喜欢:

    inline const std::wstring getCompanyName() { return L"Test Company";}
    inline const std::wstring PRODUCT() { return getCompanyName() + L" in Canada";}
    

    您可以在中展开
    产品

    getCompanyName(); L" in Canada"
    
    所以

    印刷品

    测试公司

    正如所料

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

    • 避免使用宏(改用内联函数)
    • 避免裸指针(首选STL工具)
    < >,在C++中,我们更喜欢:

    inline const std::wstring getCompanyName() { return L"Test Company";}
    inline const std::wstring PRODUCT() { return getCompanyName() + L" in Canada";}
    

    这是一个令人讨厌的黑客行为,但实际上是可能的。将
    COMPANY
    定义为一个表达式,该表达式以文本开头,以文本结尾,并且可以隐式转换为
    常量wchar\t*

    #define COMPANY L"" + getCompanyName() + L""
    
    当然,
    getCompanyName()
    不能返回
    const wchar\t*
    ,因为
    操作符+
    不是为两个指针定义的,它将对地址而不是字符串起作用

    您基本上需要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 ... */ }
    

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

    这是一个令人讨厌的黑客攻击,但实际上是可能的。将
    COMPANY
    定义为一个表达式,该表达式以文本开头,以文本结尾,并且可以隐式转换为
    常量wchar\t*

    #define COMPANY L"" + getCompanyName() + L""
    
    当然,
    getCompanyName()
    不能返回
    const wchar\t*
    ,因为
    操作符+
    不是为两个指针定义的,它将对地址而不是字符串起作用

    您基本上需要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 ... */ }
    


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

    我认为,你所要求的根本不可能。其他宏希望能够执行编译时字符串连接。如果不允许更改其他宏,唯一可能的结论是连接的操作数也必须是编译时常量(字符串文字)。如果无法重新定义产品-没有有效的方法-编译时字符串连接需要编译时常量。顺便说一句,使用“;”“由于代码”~>中有太多的宏,所以是时候更改代码了。@keltar:是的,编译时字符串串联需要编译时常量。但这只意味着宏扩展必须以它们开始和结束,而不是它不能包含任何其他内容。@JanHudec如果它包含其他内容,则不再是编译时(也不是预处理器连接)。乐观主义者仍有一些机会抓住这个机会,但我不指望它。我认为,你们的要求根本不可能实现。其他宏希望能够执行编译时字符串连接。如果不允许更改其他宏,唯一可能的结论是连接的操作数也必须是编译时常量(字符串文字)。如果无法重新定义产品-没有有效的方法-编译时字符串连接需要编译时常量。顺便说一句,使用“;”“由于代码”~>中有太多的宏,所以是时候更改代码了。@keltar:是的,编译时字符串串联需要编译时常量。但这只意味着宏扩展必须以它们开始和结束,而不是它不能包含任何其他内容。@JanHudec如果它包含其他内容,则不再是编译时(也不是预处理器连接)。乐观主义者仍然有一些机会抓住这种情况,但我不会指望它-1:除非我大错特错(如果是这样的话,一定要指出),否则它甚至不会编译,所以不会打印任何内容。对不起,我忘记了
    产品
    变量。事实上,wprintf(产品)并不是编译的。首先,是语法错误。其次,OP的宏有分号,因此它应该是
    const wchar\u t*product=getCompanyName();L“在加拿大”,最后一个字符串常量为no op,因此将被丢弃。是否有方法对函数getCompanyName()进行字符串化,使其像横向的一样?通过上次编辑,我认为这是正确的,因此删除了向下投票。-1:除非我大错特错(如果是这样的话,请指出),否则这甚至不会编译,所以它不会打印任何东西。对不起,我忘记了
    product
    变量。事实上,wprintf(产品)不是compi