C++ C++;通过此函数的所有路径将在宏中调用自身?

C++ C++;通过此函数的所有路径将在宏中调用自身?,c++,recursion,enums,C++,Recursion,Enums,嘿,伙计们,我已经写了一个宏来轻松定义枚举运算符,现在 警告:通过此函数的所有路径都将调用自身 我知道这意味着函数是递归的,但是在哪里呢 #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))

嘿,伙计们,我已经写了一个宏来轻松定义枚举运算符,现在

警告:通过此函数的所有路径都将调用自身

我知道这意味着函数是递归的,但是在哪里呢

#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)); }
但是函数调用自身的位置在哪里?我如何解决这个问题? 它现在已经修复,对于每个需要这样东西的人来说,这个模板版本应该可以工作,我认为:

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枚举运算符&(const ENUM a,const ENUM b)noexcept{return(ENUM(static_cast(a)&static_cast(b));}
模板
constexpr枚举运算符|(const ENUM a,const ENUM b)noexcept{return(ENUM(static_cast(a)| static_cast(b));}
模板
constexpr枚举运算符^(const ENUM a,const ENUM b)noexcept{return(ENUM(static_cast(a)^ static_cast(b));}
模板
constexpr枚举运算符~(const ENUM a)noexcept{return ENUM(~static_cast(a));}
模板
内联枚举和运算符&=(常量枚举&a,常量枚举b)noexcept{return(重新解释强制转换((枚举类型&)a&=(枚举类型)b));}
模板
内联枚举和运算符^=(常量枚举和a,常量枚举b)无异常{返回(重新解释强制转换((枚举类型&)a^=(枚举类型)b);}
模板
内联枚举和运算符|=(常量枚举&a,常量枚举b)无异常{返回(重新解释强制转换((枚举类型&)a |=(枚举类型)b))}
更改:

constexpr et operator~(const et a) noexcept { return ~(a); }

constexpr-et操作符~(const-et a)noexcept{return-et(~static_-cast(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)
#包括
#定义位掩码运算符(et、ut)\
constexpr et操作符&(const et a,const et b)noexcept{return(et(static_cast(a)&static_cast(b));}\
constexpr et操作符|(const et a,const et b)noexcept{return(et(static_cast(a)| static_cast(b)))}\
constexpr et operator^(const et a,const et b)noexcept{return(et(static_cast(a)^ static_cast(b));}\
constexpr-et算子(const-et-a)noexcept{return-et(~static_-cast(a));}\
内联et&运算符&=(常量et&a,常量et b)noexcept{return(reinterpret_cast((ut&)a&=(ut)b));}\
内联et&operator^=(常量et&a,常量et b)noexcept{return(reinterpret_cast((ut&)a^=(ut)b));}\
内联et&运算符|=(常量et&a,常量et b)noexcept{return(reinterpret_cast((ut&)a |=(ut)b))}
枚举kRUNTIME_标志:int16_t
{
kRUNTIME_FLAGS_DEF=0b010,
kRUNTIME\u标志\u否\u运行时\u统计信息\u录制=0b0100,
kRUNTIME_标志_启用_终端=0b01000,
kRUNTIME\u标志\u启用\u编辑\u模式=0b010000,
kRUNTIME\u标志\u允许\u编辑\u模式\u开关=0b0100000,
kRUNTIME_标志_停止=0b01000000,
kRUNTIME\u标志\u允许\u自动\u跨步\u刷新=0b010000000
};
定义位掩码运算符(kRUNTIME标志,int16)

< conxPr.ET运算符~(const et a),除了{Read ~(a);} /Cuth>看起来像是忘记了静态代码在代码< > conxPR et运算符~(const et a),除了{Read ~(a);} /Cuff>一般来说,C++中应该避免除保护和条件编译之外的宏。你应该可以用静态方法和模板来做你需要的一切。是的,我知道也许我以后会用模板来实现。我添加了一个模板版本。他真的应该用模板来实现。就是这样!非常感谢;)是的,我忘记了按位的静态转换不是!

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)