c++ - C++ 通过这个函数的所有路径都会在宏中调用自己?
问题描述
嘿伙计们,我写了一个宏来轻松定义枚举运算符,我得到了
警告:通过此函数的所有路径都将调用自身
我知道这意味着函数是递归的,但是在哪里呢?
#define DEFINE_BITMASKENUM_OPERATORS(et, ut) \
constexpr et operator &(const et a, const et b) noexcept { return (et(static_cast<ut>(a) & static_cast<ut>(b))); } \
constexpr et operator |(const et a, const et b) noexcept { return (et(static_cast<ut>(a) | static_cast<ut>(b))); } \
constexpr et operator ^(const et a, const et b) noexcept { return (et(static_cast<ut>(a) ^ static_cast<ut>(b))); } \
constexpr et operator~(const et a) noexcept { return ~(a); } \
inline et& operator&=(const et& a, const et b) noexcept { return (reinterpret_cast<et&>((ut&)a &= (ut)b)); } \
inline et& operator^=(const et& a, const et b) noexcept { return (reinterpret_cast<et&>((ut&)a ^= (ut)b)); } \
inline et& operator|=(const et& a, const et b) noexcept { return (reinterpret_cast<et&>((ut&)a |= (ut)b)); }
et 是枚举类型, ut 是基础类型。它将像这样使用:
enum kRUNTIME_FLAGS : short16
{
kRUNTIME_FLAGS_DEF = 0b010,
kRUNTIME_FLAGS_NO_RUNTIME_STATISTICS_RECORDING = 0b0100,
kRUNTIME_FLAGS_ENABLE_TERMINAL = 0b01000,
kRUNTIME_FLAGS_ENABLE_EDIT_MODE = 0b010000,
kRUNTIME_FLAGS_ALLOW_EDIT_MODE_SWITCH = 0b0100000,
kRUNTIME_FLAGS_STOP = 0b01000000,
kRUNTIME_FLAGS_ALLOW_AUTO_STRIDE_FLUSH = 0b010000000
};
DEFINE_BITMASKENUM_OPERATORS(kRUNTIME_FLAGS, short16)
但是函数在哪里调用自己,我该如何解决这个问题?它现在已修复,对于需要这样的东西的每个人,我认为这个模板版本应该可以工作:
template<typename ENUM, typename ENUM_TYPE = typename std::underlying_type<ENUM>::type>
constexpr ENUM operator&(const ENUM a, const ENUM b) noexcept { return (ENUM(static_cast<ENUM_TYPE>(a) & static_cast<ENUM_TYPE>(b))); }
template<typename ENUM, typename ENUM_TYPE = typename std::underlying_type<ENUM>::type>
constexpr ENUM operator|(const ENUM a, const ENUM b) noexcept { return (ENUM(static_cast<ENUM_TYPE>(a) | static_cast<ENUM_TYPE>(b))); }
template<typename ENUM, typename ENUM_TYPE = typename std::underlying_type<ENUM>::type>
constexpr ENUM operator^(const ENUM a, const ENUM b) noexcept { return (ENUM(static_cast<ENUM_TYPE>(a) ^ static_cast<ENUM_TYPE>(b))); }
template<typename ENUM, typename ENUM_TYPE = typename std::underlying_type<ENUM>::type>
constexpr ENUM operator~(const ENUM a) noexcept { return ENUM(~static_cast<ENUM_TYPE>(a)); }
template<typename ENUM, typename ENUM_TYPE = typename std::underlying_type<ENUM>::type>
inline ENUM& operator&=(const ENUM& a, const ENUM b) noexcept { return (reinterpret_cast<ENUM&>((ENUM_TYPE&)a &= (ENUM_TYPE)b)); }
template<typename ENUM, typename ENUM_TYPE = typename std::underlying_type<ENUM>::type>
inline ENUM& operator^=(const ENUM& a, const ENUM b) noexcept { return (reinterpret_cast<ENUM&>((ENUM_TYPE&)a ^= (ENUM_TYPE)b)); }
template<typename ENUM, typename ENUM_TYPE = typename std::underlying_type<ENUM>::type>
inline ENUM& operator|=(const ENUM& a, const ENUM b) noexcept { return (reinterpret_cast<ENUM&>((ENUM_TYPE&)a |= (ENUM_TYPE)b)); }
解决方案
改变:
constexpr et operator~(const et a) noexcept { return ~(a); }
至
constexpr et operator~(const et a) noexcept { return et(~static_cast<ut>(a)); }
它应该在没有警告的情况下编译。
#include <cstdint>
#define DEFINE_BITMASKENUM_OPERATORS(et, ut) \
constexpr et operator &(const et a, const et b) noexcept { return (et(static_cast<ut>(a) & static_cast<ut>(b))); } \
constexpr et operator |(const et a, const et b) noexcept { return (et(static_cast<ut>(a) | static_cast<ut>(b))); } \
constexpr et operator ^(const et a, const et b) noexcept { return (et(static_cast<ut>(a) ^ static_cast<ut>(b))); } \
constexpr et operator~(const et a) noexcept { return et(~static_cast<ut>(a)); } \
inline et& operator&=(const et& a, const et b) noexcept { return (reinterpret_cast<et&>((ut&)a &= (ut)b)); } \
inline et& operator^=(const et& a, const et b) noexcept { return (reinterpret_cast<et&>((ut&)a ^= (ut)b)); } \
inline et& operator|=(const et& a, const et b) noexcept { return (reinterpret_cast<et&>((ut&)a |= (ut)b)); }
enum kRUNTIME_FLAGS : int16_t
{
kRUNTIME_FLAGS_DEF = 0b010,
kRUNTIME_FLAGS_NO_RUNTIME_STATISTICS_RECORDING = 0b0100,
kRUNTIME_FLAGS_ENABLE_TERMINAL = 0b01000,
kRUNTIME_FLAGS_ENABLE_EDIT_MODE = 0b010000,
kRUNTIME_FLAGS_ALLOW_EDIT_MODE_SWITCH = 0b0100000,
kRUNTIME_FLAGS_STOP = 0b01000000,
kRUNTIME_FLAGS_ALLOW_AUTO_STRIDE_FLUSH = 0b010000000
};
DEFINE_BITMASKENUM_OPERATORS(kRUNTIME_FLAGS, int16_t)
推荐阅读
- curl - 从 Curl 到 Postman(双重授权标头?)
- python - 会员离开语音频道时有什么方法可以发挥作用吗?
- r - 使用“...”传递多个参数时,指定 R 一次采用一个参数
- python - 更新 JSON 文件时如何检查数据是否退出
- javascript - 在 LWC 上使用 FontAwesome
- laravel - Laravel 8 Fortify Redirect 基于角色而没有 jetstream
- google-cloud-platform - Flink PubsubIO 错误“Cannot nackAll on persisting checkpoint”
- elasticsearch - 过滤 DSL 查询搜索 - Elasticsearch
- firebase - 使用 Firebase 函数的条带化错误:错误:您没有提供 API 密钥。您需要在 Authorization 标头中提供您的 API 密钥
- node.js - 如何使用 UTC,同时使用 prisma.js 和 express.js 项目中的一般定义模型