如果宏有括号,有没有办法让宏有不同的行为?
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
我正在尝试做这样的事情:
#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