如何使用Q_FLAG_NS宏?
我对NS和K民建联的新Qt支持命名空间的解读表明,使用这个宏应该提供按位运算符,但不管我尝试了什么,
../main.cpp:11:11: error: invalid operands to binary expression
('App::ComponentRequirementState' and 'App::ComponentRequirementState')
r = r | App::ComponentRequirementState::AlwaysRequired;
~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我放置了一个最小代码示例这里。
奇怪的是,我可以在ComponentRequirementStat枚举的定义中使用位运算符,而不是在它之外。
我是不是用错了这个宏?还是根本不起作用?
当我手动定义操作符时,比如说,
auto operator|(const App::ComponentRequirementState a, App::ComponentRequirementState b) -> App::ComponentRequirementState
{
return static_cast<App::ComponentRequirementState>(static_cast<unsigned int>(a) | static_cast<unsigned int>(b));
}那就成功了。
发布于 2018-01-15 21:38:14
使用Qt的
Q_FLAGS_NS不提供按位操作支持:它只是在Qt元对象系统中注册类型。
如果您希望注册类型并提供类型安全的按位运算符支持,则应使用QFlags。
文件中的一个例子是:
class MyClass
{
public:
enum Option {
NoOptions = 0x0,
ShowTabs = 0x1,
ShowAll = 0x2,
SqueezeBlank = 0x4
};
Q_DECLARE_FLAGS(Options, Option)
...
};
Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::Options)您也可以跳过其中的大部分内容并这样做:
// not type-safe, unscoped enum. You should likely define this
// in a namespace or class.
enum Option {
NoOptions = 0x0,
ShowTabs = 0x1,
ShowAll = 0x2,
SqueezeBlank = 0x4
};
// type-safe flag
using Options = QFlags<Option>;您也可以为此目的使用非作用域枚举,或者使用宏帮助您为作用域枚举提供按位运算符支持:
类型-带作用域Enum的安全位操作
下面是您可以自由使用的宏(公共域,我自己的代码,尽管您应该修改宏,以确保它具有避免任何名称冲突的前缀)来向作用域枚举添加按位操作。这目前需要C++14支持,但是,将std::underlying_type_t<T>更改为typename std::underlying_type<T>::type允许宏在C++11中工作。
使用
enum class enum1_t
{
A = 1,
B,
C,
D,
E,
};
enum class enum2_t
{
F = 1,
G,
H,
I,
J,
};
ENUM_FLAG(enum1_t) // allow bitwise operations for enum1_t and enum1_t
ENUM_FLAG(enum1_t, enum2_t) // allow bitwise operations for enum1_t and enum2_t码
#include <type_traits>
#include <cstdint>
// HELPERS
// -------
/**
* \brief Get enum underlying type.
*/
template <typename T>
inline std::underlying_type_t<T> int_t(T t)
{
return static_cast<std::underlying_type_t<T>>(t);
}
// MACROS
// ------
/**
* \brief Macro to define enum operators between enumerations.
*
* Supports `&`, `&=`, `|`, `|=`, `^`, `^=`, `~`, and bool conversion.
*/
#define ENUM_FLAG2(lhs_t, ths_t) \
/* \brief Bitwise or operator. */ \
inline lhs_t operator|(lhs_t lhs, ths_t rhs) noexcept \
{ \
return static_cast<lhs_t>(int_t(lhs) | int_t(rhs)); \
} \
\
/* \brief Bitwise or assignment operator. */ \
inline lhs_t & operator|=(lhs_t &lhs, ths_t rhs) noexcept \
{ \
lhs = static_cast<lhs_t>(int_t(lhs) | int_t(rhs)); \
return lhs; \
} \
\
/* \brief Bitwise and operator. */ \
inline lhs_t operator&(lhs_t lhs, ths_t rhs) noexcept \
{ \
return static_cast<lhs_t>(int_t(lhs) & int_t(rhs)); \
} \
\
/* \brief Bitwise and assignment operator. */ \
inline lhs_t & operator&=(lhs_t &lhs, ths_t rhs) noexcept \
{ \
lhs = static_cast<lhs_t>(int_t(lhs) & int_t(rhs)); \
return lhs; \
} \
\
/* \brief Bitwise xor operator. */ \
inline lhs_t operator^(lhs_t lhs, ths_t rhs) noexcept \
{ \
return static_cast<lhs_t>(int_t(lhs) ^ int_t(rhs)); \
} \
\
/* \brief Bitwise xor assignment operator. */ \
inline lhs_t & operator^=(lhs_t &lhs, ths_t rhs) noexcept \
{ \
lhs = static_cast<lhs_t>(int_t(lhs) ^ int_t(rhs)); \
return lhs; \
}
/**
* \brief Set enumeration flags within the same enum.
*/
#define ENUM_FLAG1(enum_t) \
ENUM_FLAG2(enum_t, enum_t) \
\
/* \brief Bitwise negation operator. */ \
inline enum_t operator~(enum_t value) noexcept \
{ \
return static_cast<enum_t>(~int_t(value)); \
} \
\
/* \brief Negation operator. */ \
inline bool operator!(enum_t value) noexcept \
{ \
return int_t(value) == 0; \
}
/**
* \brief Macros to grab the proper bit-wise flag setter.
* `ENUM_ID` is required for MSVC compatibility, since MSVC
* has issues in expanding `__VA_ARGS__` for the dispatcher.
* Don't remove it, even if the above code works without it
* for GCC and Clang.
*/
#define ENUM_ID(x) x
#define GET_ENUM_FLAG(_1,_2,NAME,...) NAME
#define ENUM_FLAG(...) ENUM_ID(GET_ENUM_FLAG(__VA_ARGS__, ENUM_FLAG2, ENUM_FLAG1)(__VA_ARGS__))https://stackoverflow.com/questions/48269664
复制相似问题