我在一个表示位标志的类中有一个枚举。
class Foo
{
enum Bar
{
BAR0 = 0x1,
BAR1 = 0x2,
BAR2 = 0x4,
};
}
我还在课程operator|
之外为枚举Bar
定义了Foo
。
constexpr Foo::Bar operator| (Foo::Bar lhs, Foo::Bar rhs)
{
return static_cast<Foo::Bar>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
我还希望constexpr
变量BAR_ALL
是Bar
类Foo
内所有现有标志的组合。我尝试了以下操作,但它没有使用错误error: #28: expression must have a constant value
进行编译。
完整代码:
class Foo
{
enum Bar
{
BAR0 = 0x1,
BAR1 = 0x2,
BAR2 = 0x4,
};
friend constexpr Bar operator| (Bar lhs, Bar rhs);
static constexpr Bar BAR_ALL = BAR0 | BAR1 | BAR2;
};
constexpr Foo::Bar operator| (Foo::Bar lhs, Foo::Bar rhs)
{
return static_cast<Foo::Bar>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
我认为编译器不知道BAR0 | BAR1 | BAR2
是constexpr
是有道理的,因为稍后在代码中定义了运算符。我的问题是如何获得Foo::BAR_ALL
变量constexpr
所需的效果。
提前感谢您的建议/帮助!
答案 0 :(得分:2)
这是一个具有您想要的功能的工作版本。
class Foo
{
enum Bar
{
BAR0 = 0x1,
BAR1 = 0x2,
BAR2 = 0x4,
BAR_ALL_ = BAR0 | BAR1 | BAR2
};
friend constexpr Bar operator| (Bar lhs, Bar rhs);
public:
static Bar constexpr BAR_ALL = Bar::BAR_ALL_;
};
constexpr Foo::Bar operator| (Foo::Bar lhs, Foo::Bar rhs)
{
return static_cast<Foo::Bar>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
template <int I>
struct test_constexpr_bar_all {};
int main()
{
int x{ 5 };
// test_constexpr_bar_all<x> t1; // fails to compile because x is not a constexpr
test_constexpr_bar_all<Foo::BAR_ALL> t1; // compiles properly
}
如果您想公开您的枚举,那么您可以摆脱static Bar constexpr BAR_ALL = Bar::BAR_ALL_;
并只需通过Foo::Bar::BAR_ALL_
访问它。
我将如何做到这一点:
class Foo
{
public:
enum Bar
{
BAR0 = 0x1,
BAR1 = 0x2,
BAR2 = 0x4,
BAR_ALL = BAR0 | BAR1 | BAR2
};
private:
friend constexpr Bar operator| (Bar lhs, Bar rhs);
};
constexpr Foo::Bar operator| (Foo::Bar lhs, Foo::Bar rhs)
{
return static_cast<Foo::Bar>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
template <Foo::Bar I>
struct test_constexpr_bar_all {};
int main()
{
test_constexpr_bar_all<Foo::Bar::BAR_ALL> t1;
}