首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QT5.9中的Q_FLAG_NS不提供按位运算符

QT5.9中的Q_FLAG_NS不提供按位运算符
EN

Stack Overflow用户
提问于 2018-01-15 19:43:25
回答 2查看 475关注 0票数 1

如何使用Q_FLAG_NS宏?

我对NSK民建联的新Qt支持命名空间的解读表明,使用这个宏应该提供按位运算符,但不管我尝试了什么,

代码语言:javascript
复制
../main.cpp:11:11: error: invalid operands to binary expression 
('App::ComponentRequirementState' and 'App::ComponentRequirementState')
    r = r | App::ComponentRequirementState::AlwaysRequired;
        ~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我放置了一个最小代码示例这里

奇怪的是,我可以在ComponentRequirementStat枚举的定义中使用位运算符,而不是在它之外。

我是不是用错了这个宏?还是根本不起作用?

当我手动定义操作符时,比如说,

代码语言:javascript
复制
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));
}

那就成功了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-15 21:38:14

使用Qt的

Q_FLAGS_NS不提供按位操作支持:它只是在Qt元对象系统中注册类型。

如果您希望注册类型并提供类型安全的按位运算符支持,则应使用QFlags

文件中的一个例子是:

代码语言:javascript
复制
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)

您也可以跳过其中的大部分内容并这样做:

代码语言:javascript
复制
// 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中工作。

使用

代码语言:javascript
复制
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

代码语言:javascript
复制
#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__))
票数 1
EN

Stack Overflow用户

发布于 2018-01-15 21:11:16

Q_FLAG_NS不是问题所在。这是由新的C++11 )造成的。它们不隐式转换为整数类型,并且不能将它们用于只为整型[1][2]定义的按位操作。

您必须自己提供这些操作,或者使用未限定的、旧的枚举。

提供这些操作的一个问题是,它需要将所有可能的标志组合定义为枚举值或返回整数类型:

代码语言:javascript
复制
??? operator|(App::ComponentRequirementState lhs, App::ComponentRequirementState rhs);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48269664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档