I have the following code:
main.cpp
#include <cstdint>
#include <type_traits>
enum class FooEnum : uint8_t{
Foo1 = 0,
Foo2 = 1
};
constexpr uint32_t& operator|= (uint32_t& lhs, FooEnum rhs) {
return lhs |= 1u << static_cast<uint8_t>(rhs);
}
int main() {
uint32_t bar{0};
bar|=FooEnum::Foo1;
}
因此,
|=
运算符应该接受枚举并设置位,其位置对应于其整数值。在fedora 21上使用clang++ 3.5.0编译时,一切正常,但在使用g++ 4.9.2编译时,它会抛出一个错误,指出这不是一个常量表达式:
main.cpp: In function ‘constexpr uint32_t& operator|=(uint32_t&, FooEnum)’:
main.cpp:16:2: error: expression ‘(lhs = (lhs | (1u << ((int)rhs))))’ is not a constant-expression
}
^
这对于所有类型的编译器标志组合都是正确的,但您可以使用g ++ -std = c ++ 11 -o a.out main.cpp
进行测试(c ++ 14没有区别)。
所以我的问题是:
- 哪个编译器是正确的(为什么)?
- 是否有一种实现
operator | =
的方法,使得g ++将其接受为constexpr
?
编辑:
如果你想知道,为什么我首先尝试声明运算符为constexpr
,尽管在示例中不需要:
在我的实际代码中,我正在使��|=
-运算符来实现(constexpr)|
-运算符,我希望它能在constexpr表达式中使用,但在那之前,我遇到了两个编译器之间的差异,没有意识到gcc4.9并不完全支持c ++ 14(但接受-std=c++14
标志)。
当使用运算符实际初始化全局constexpr变量时,即使clang也只能使用c ++ 14标志编译它。