如果有括号,有没有办法使宏具有不同的行为

Is there a way to make a macro have different behavior if it has parenthesis?

本文关键字:有没有 如果      更新时间:2023-10-16

我正在尝试做这样的事情:

#define FOO printf("No parenn");
#define FOO(x) printf(x);

有没有办法使用 c++ 宏来做到这一点?

No. 给定的宏名称可以是纯的("类似对象")或"类似函数",而不是两者兼而有之。

我不建议这样做,但在C++本身的帮助下可能的,

#include <iostream>
template<typename T>
struct CustomMessage
{
    const T& t;
    CustomMessage(const T& t) : t(t)
    {}
};
struct DefaultMessage
{
    template<typename T> CustomMessage<T> operator() (const T& t)
    {
        return {t};
    }
};
template<typename T>
std::ostream& operator<< (std::ostream& os, const CustomMessage<T>& message)
{
    return os << message.t;
}
std::ostream& operator<< (std::ostream& os, const DefaultMessage& message)
{
    return os << "no parenn";
}
using namespace std;
#define FOO std::cout << DefaultMessage{}
int main() {
    int x = 42;
    FOO;
    FOO(x);
    return 0;
}

活一个 Ideone https://ideone.com/VboP8R

不是那么直接:单个宏必须是"普通"或"类似函数"。

但是,你可以朝这个方向做一些事情。

您可以使用可变参数宏并根据参数的数量更改行为。

您可以使用上述内容构建要委派给的目标宏的名称:

#define NUM_ARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
#define NUM_ARGS(...) NUM_ARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define CONCAT_(a, b) a##b
#define CONCAT(a, b) CONCAT_(a, b)
#define CAKE_1(X) some-interesting-code-here
#define CAKE_2(X, Y) some-different-interesting-code-here
#define CAKE(...) CONCAT(CAKE_, NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)

在上面,用 1 个参数调用 CAKE() 将调用CAKE_1,用 2 调用它将调用CAKE_2。

出于

清晰等原因,做这种事情是否是一个好主意,留给读者作为练习。

相关文章: