【发布时间】:2019-06-18 02:14:31
【问题描述】:
如何编写一个宏来根据其参数的类型执行不同的操作?
我有一个宏需要处理可以具有两种类型之一的参数。
#include <typeinfo>
enum class Coolness { kUndefined, kUncool, kCool };
enum class Tallness { kUndefined, kShort, kTall };
void MakePerson (Coolness coolness, Tallness tallness) {}
// Provide a way to make a person by only providing Coolness or Tallness.
#define MAKE_PERSON(x) \
({ \
if (typeid(x) == typeid(Coolness)) { \
MakePerson(((x)), Tallness::kUndefined); \
} else { \
MakePerson(Coolness::kUndefined, (x)); \
} \
})
int main()
{
MAKE_PERSON(Coolness::kUncool);
MAKE_PERSON(Tallness::kTall);
}
(我们可以在这里使用默认参数,但在实际代码中我们实际上必须使用宏。)
编译器对 main 中的两个调用都抛出错误:
main.cpp: In function ‘int main()’:
main.cpp:23:43: error: cannot convert ‘Coolness’ to ‘Tallness’ for argument ‘2’ to ‘void MakePerson(Coolness, Tallness)’
MakePerson(Coolness::kUndefined, (x)); \
^
main.cpp:29:3: note: in expansion of macro ‘MAKE_PERSON’
MAKE_PERSON(Coolness::kUncool);
^~~~~~~~~~~
main.cpp:21:45: error: cannot convert ‘Tallness’ to ‘Coolness’ for argument ‘1’ to ‘void MakePerson(Coolness, Tallness)’
MakePerson(((x)), Tallness::kUndefined); \
^
main.cpp:30:3: note: in expansion of macro ‘MAKE_PERSON’
MAKE_PERSON(Tallness::kTall);
^~~~~~~~~~~
(在https://www.onlinegdb.com/online_c++_compiler完成)
我们不能像this question那样使用__builtin_types_compatible_p,因为我们的编译器没有。
如何编写一个宏来根据其参数的类型执行不同的操作?
【问题讨论】:
-
这就是 C++ 模板的用途。这是 C++,而不是带有 shudder 宏的史前 C...
-
不幸的是,我认为我需要在实际问题中使用宏 - 我正在开发需要访问
__LINE__和__FILE__的日志基础设施。这只是我能想到的最小的例子。 -
由于
__LINE__和__FILE__总是相同的类型,在任何地方,都不清楚这有什么关系。 -
@SamVarshavchik,我想说的是我正在努力启用 LOG(...) 调用,我想我需要在这里使用一个宏,这样我才能得到这条线# 和调用发生位置的文件(否则我只会得到实现日志校准的行# 和文件)。但我想你是说宏的实现应该使用 C++ 模板,而不是说不应该使用宏,永远?
标签: c++