如何使宏处理不同类型的参数?
How can I make a macro handle different types of arguments?
如何编写一个根据其参数类型执行不同操作的宏?
我有一个宏,需要处理可以具有两种类型之一的参数。
#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 完成)
我们不能像这个问题一样使用__builtin_types_compatible_p
因为我们的编译器没有这个。
如何编写一个根据其参数类型执行不同操作的宏?
使用简单的函数重载,不要试图使宏比它需要的更智能:
enum class Coolness { kUndefined, kUncool, kCool };
enum class Tallness { kUndefined, kShort, kTall };
void MakePerson (Coolness coolness, Tallness tallness)
{
...
}
inline void MakePerson (Coolness coolness)
{
MakePerson(coolness, Tallness::kUndefined);
}
inline void MakePerson (Tallness tallness)
{
MakePerson(Coolness::kUndefined, tallness);
}
#define MAKE_PERSON(x)
{
// use __FILE__ and __LINE__ as needed...
MakePerson(x);
}
int main()
{
MAKE_PERSON(Coolness::kUncool);
MAKE_PERSON(Tallness::kTall);
}
现场演示
欢迎其他建议,但我们最终做的是使用static_cast告诉编译器参数是什么类型:
#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.
// Static cast is used because the compiler fails to typecheck the
// branches correctly without it.
#define MAKE_PERSON(x)
({
if (typeid(x) == typeid(Coolness)) {
MakePerson(static_cast<Coolness>((x)), Tallness::kUndefined);
} else {
MakePerson(Coolness::kUndefined, static_cast<Tallness>((x)));
}
})
int main()
{
MAKE_PERSON(Coolness::kUncool);
MAKE_PERSON(Tallness::kTall);
}
...Program finished with exit code 0
相关文章:
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 在模板中显示参数的类型
- 列表参数的类型定义
- 视觉工作室 2017;启用 /permissive 时,类型 "const wchar_t *" 的参数与类型 "PWSTR" 的参数不兼容
- 是否可以在C++中有一个"generic"模板参数,该参数可以是非类型模板参数或类型?
- 如果可推导类型上有替换,可变参数模板类型推导会使编译器崩溃
- 通过引用传递参数时C++类型转换
- 推断指针非类型模板参数的类型
- 可变参数模板参数扩展 类型为 std::function 的类成员
- 类具有相同的接口,但参数的类型不同
- 将强制转换简化为取决于参数的类型
- 具有可变参数非类型参数的模板专用化
- 使模板函数按函数参数选择类型
- 为表示一个或多个操作的C++函数的int参数寻找类型安全的替换
- 编译器给出错误:format 指定类型 'float *',但参数的类型'double' [-Wformat]
- 参数数据类型未知的可变参数函数
- 将可变参数模板类型转换为 void,预期')'之前
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- 将参数列表未知的可变参数模板类型定义为 std::map 值类型
- C++ 类型 "char" 的参数与类型 "const char" 的参数不兼容