【问题标题】:compiling error while calling a function from macro从宏调用函数时编译错误
【发布时间】:2021-10-12 20:35:34
【问题描述】:

我们有一个宏 {TT(msg)},在该宏中,我们正在调用一个函数,其参数与宏中收到的参数相同,即“msg”。从宏调用的函数需要一个字符串参数。现在假设如果像 TT("argument") 这样调用宏,那么程序正在编译并按预期工作,但是如果我们像 TT("argument" 那么它给出以下编译错误。

ma​​in.cpp:14:14: 错误:'const char [4]' 和'int' 类型的无效操作数到二进制'operator

问题的原因:当调用 TT() 宏时,它将直接调用带有参数的 func() API,因为 msg 有一些其他值 "XYZ" func() 无法处理。所以我们需要以某种方式处理这个问题。

#include <iostream>

using namespace std;
#define TT(msg) func(msg);

void func (string msg) {
    cout << msg;
    
}

int main()
{   
    int i=9;
    TT ("XYZ"<<i);
    return 0;
}

【问题讨论】:

    标签: c++ function macros g++ ostream


    【解决方案1】:

    按要求回答问题...在我看来这是个坏主意,但可能(请参阅答案底部的方法):

    为什么我认为你不应该介绍这种语法?

    查看TT ("XYZ"&lt;&lt;i); 时,给人的印象是"XYZ"&lt;&lt;i 表达式的结果被传递给TT()。即人们会期望以下工作,但他们不能。这只是简单的误导

    auto tmp = "XYZ" << i;  // Nope, can't do this
    TT (tmp);
    
    TT (("XYZ" << i)); // Doesn't work either.
    

    我建议改为:

    using namespace std;
    #define TT(msg) func(msg);
    
    std::ostream& func(string msg) {
        cout << msg;
        return cout;
    }
    
    int main()
    {   
        int i=9;
        TT ("XYZ") << i;
    
        // or just call func() directly. TT() doesn't serve any purpose:
        func("XYZ") << i;
        return 0;
    }
    

    它实际上是相同的语法,并且不会导致任何混淆。最重要的是,它不必构建中间字符串。

    如果您别无选择,只能实现您发布的语法,您可以这样做:

    “复制粘贴”整个消息表达式作为std::ostringstreamoperator&lt;&lt;() 的右侧。将整个事情包装在一个立即调用的 lambda 中;

    #include <sstream>
    #define TT(msg_expr) func([&] {                            \
        std::ostringstream tmp_stream_avoid_name_collisions{}; \
        tmp_stream_avoid_name_collisions << msg_expr;          \
        return tmp_stream_avoid_name_collisions.str();         \
    }());
    

    【讨论】:

    • 得到这个错误:main.cpp:12:62:错误:'class std::basic_ostream'没有名为'str'的成员;您指的是 “setf” 吗? #define TT(msg_expr) func((std::ostringstream{}
    • 那是因为我登陆的版本不能很好地配合operator&lt;&lt;() 经常超载的方式。我已将答案恢复为我原来的、更丑陋但显然更好的实现方式。
    猜你喜欢
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2018-05-05
    • 2016-02-16
    • 2014-04-01
    • 1970-01-01
    相关资源
    最近更新 更多