为什么将 int 分配给枚举类型在 OpenCV _InputArray::kind() 中有效?
Why is assigning an int to enum type valid in OpenCV _InputArray::kind()?
我认为在 C++ 中向枚举变量赋值和 int 值是无效的,并且已经有验证这一点的问题,例如 .
但是我只看到下面的代码没有导致编译错误:
// https://github.com/opencv/opencv/blob/4.x/modules/core/include/opencv2/core/mat.hpp#L158-L265
class CV_EXPORTS _InputArray
{
public:
enum KindFlag { //!! KindFlag is an enum type
KIND_SHIFT = 16,
FIXED_TYPE = 0x8000 << KIND_SHIFT,
FIXED_SIZE = 0x4000 << KIND_SHIFT,
KIND_MASK = 31 << KIND_SHIFT,
...
}
...
};
// https://github.com/opencv/opencv/blob/4.x/modules/core/src/matrix_wrap.cpp#L370-L378
_InputArray::KindFlag _InputArray::kind() const
{
KindFlag k = flags & KIND_MASK; //!! this line, I think it is assign enum type var `k` with int value `flag & KIND_MASK`, but it it not cause compile error
#if CV_VERSION_MAJOR < 5
CV_DbgAssert(k != EXPR);
CV_DbgAssert(k != STD_ARRAY);
#endif
return k;
}
我尝试用下面的代码实现一个最小的InputArray_
class,这会导致编译错误,使用与上面相同的assigne,这让我很困惑:
// what.cpp
class InputArray_
{
public:
enum KindFlag {
KIND_SHIFT = 16,
KIND_MASK = 31 << KIND_SHIFT,
NONE = 0 << KIND_SHIFT,
MAT = 1 << KIND_SHIFT
};
bool empty() const;
InputArray_::KindFlag kind() const;
public:
InputArray_();
protected:
int flags;
void* obj;
};
InputArray_::KindFlag InputArray_::kind() const
{
KindFlag k = flags & KIND_MASK; //!! now this cause compile error
return k;
}
int main()
{
}
编译器为AppleClang 13.0.0,完整错误信息为:
what.cpp:26:14: error: cannot initialize a variable of type 'InputArray_::KindFlag' with an rvalue of type 'int'
KindFlag k = flags & KIND_MASK;
^ ~~~~~~~~~~~~~~~~~
1 error generated.
有谁知道为什么OpenCV的不会导致编译错误?
opencv 定义运算符 &
本身,因此它不再导致 int
您可以在您链接的部分下方看到它
__CV_ENUM_FLAGS_BITWISE_AND(_InputArray::KindFlag, int, _InputArray::KindFlag)
宏的实现
#define __CV_ENUM_FLAGS_BITWISE_AND(EnumType, Arg1Type, Arg2Type) \
static inline EnumType operator&(const Arg1Type& a, const Arg2Type& b) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return static_cast<EnumType>(static_cast<UnderlyingType>(a) & static_cast<UnderlyingType>(b)); \
}
我认为在 C++ 中向枚举变量赋值和 int 值是无效的,并且已经有验证这一点的问题,例如
但是我只看到下面的代码没有导致编译错误:
// https://github.com/opencv/opencv/blob/4.x/modules/core/include/opencv2/core/mat.hpp#L158-L265
class CV_EXPORTS _InputArray
{
public:
enum KindFlag { //!! KindFlag is an enum type
KIND_SHIFT = 16,
FIXED_TYPE = 0x8000 << KIND_SHIFT,
FIXED_SIZE = 0x4000 << KIND_SHIFT,
KIND_MASK = 31 << KIND_SHIFT,
...
}
...
};
// https://github.com/opencv/opencv/blob/4.x/modules/core/src/matrix_wrap.cpp#L370-L378
_InputArray::KindFlag _InputArray::kind() const
{
KindFlag k = flags & KIND_MASK; //!! this line, I think it is assign enum type var `k` with int value `flag & KIND_MASK`, but it it not cause compile error
#if CV_VERSION_MAJOR < 5
CV_DbgAssert(k != EXPR);
CV_DbgAssert(k != STD_ARRAY);
#endif
return k;
}
我尝试用下面的代码实现一个最小的InputArray_
class,这会导致编译错误,使用与上面相同的assigne,这让我很困惑:
// what.cpp
class InputArray_
{
public:
enum KindFlag {
KIND_SHIFT = 16,
KIND_MASK = 31 << KIND_SHIFT,
NONE = 0 << KIND_SHIFT,
MAT = 1 << KIND_SHIFT
};
bool empty() const;
InputArray_::KindFlag kind() const;
public:
InputArray_();
protected:
int flags;
void* obj;
};
InputArray_::KindFlag InputArray_::kind() const
{
KindFlag k = flags & KIND_MASK; //!! now this cause compile error
return k;
}
int main()
{
}
编译器为AppleClang 13.0.0,完整错误信息为:
what.cpp:26:14: error: cannot initialize a variable of type 'InputArray_::KindFlag' with an rvalue of type 'int'
KindFlag k = flags & KIND_MASK;
^ ~~~~~~~~~~~~~~~~~
1 error generated.
有谁知道为什么OpenCV的不会导致编译错误?
opencv 定义运算符 &
本身,因此它不再导致 int
您可以在您链接的部分下方看到它
__CV_ENUM_FLAGS_BITWISE_AND(_InputArray::KindFlag, int, _InputArray::KindFlag)
宏的实现
#define __CV_ENUM_FLAGS_BITWISE_AND(EnumType, Arg1Type, Arg2Type) \
static inline EnumType operator&(const Arg1Type& a, const Arg2Type& b) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return static_cast<EnumType>(static_cast<UnderlyingType>(a) & static_cast<UnderlyingType>(b)); \
}