如果宏有括号,有没有办法让宏有不同的行为?

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

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

#define FOO printf("No paren\n");
#define FOO(x) printf(x);

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

没有。给定的宏名称可以是普通名称 ("object-like") 或 "function-like",但不能两者都是。

不是那么直接:单个宏必须是 "plain" 或 "function like"。

但是,您可以在这方面做一些事情。

您可以使用可变参数宏并根据 number of arguments 更改行为。

您可以使用上面的方法构建要委托给的目标宏的名称:

#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.

为了清楚起见,做这种事情是否是个好主意,留作 reader.

的练习。

我不建议这样做,但是在 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 paren\n";
}

using namespace std;

#define FOO std::cout << DefaultMessage{}

int main() {
    int x = 42;
    FOO;
    FOO(x);
    return 0;
}

住一个Ideonehttps://ideone.com/VboP8R