我现在正在研究一个运动控制系统。我想使运动控制界面更加灵活,所以我想提供一个api,可以指定控制轴。
就像。
void moveTo(/*data*/, Axis which);轴参数用于定义如何处理运动数据,内部实现将根据所请求的轴检查数据。
因此,我想对Axis参数定义一个操作规则。
我尝试了位标志,定义如下。
enum class Axis : std::uint_fast16_t {
X = 1l << 0,
Y = 1l << 1,
Z = 1l << 2
};
// operator | and & and so on are also defined.它可以用于以下几个方面。
const auto which = Axis::X | Axis::Y;但是我想要的是,Axis::X =x\=x的和轴::y=在函数中无法区分它们。
我应该如何定义这样一个似乎与“操作顺序”相关的位掩码?
它似乎是通过在一个枚举中列出所有允许的组合状态来做到这一点的。但我仍然想问,是否有一个更优雅和清晰的解决方案。
或者对更好地实现这些功能有什么建议?
我希望最终的使用仍然像比特面具一样简单,我不介意在幕后做一些非常复杂的工作,我不介意使用任何第三方库。
发布于 2022-05-08 08:49:03
考虑到你只有3个轴和有限数量的组合,我建议仅仅定义它们。
enum class Axis : std::uint_fast16_t {
X = 0,
Y = 1,
Z = 2,
XX = 3,
YX = 4,
ZX = 5,
XY = 6,
YY = 7,
ZY = 8,
XZ = 9,
YZ = 10,
ZZ = 11,
XXX = 12,
YXX = 13,
ZXX = 14,
XYX = 15,
YYX = 16,
ZYX = 17,
XZX = 18,
YZX = 19,
ZZX = 20,
XXY = 21,
YXY = 22,
ZXY = 23,
XYY = 24,
YYY = 25,
ZYY = 26,
XZY = 27,
YZY = 28,
ZZY = 29,
XXZ = 30,
YXZ = 31,
ZXZ = 32,
XYZ = 33,
YYZ = 34,
ZYZ = 35,
XZZ = 36,
YZZ = 37,
ZZZ = 38,
};如果您想要以编程的方式完成它,那么您可以做的就是在每次添加一个新标志时将该值移动2,因为每个值都由2位表示。
#include <type_traits>
#include <array>
#include <iostream>
#include <bitset>
enum class Axis : std::uint_fast16_t {
X = 0b01,
Y = 0b10,
Z = 0b11,
};
Axis append_flag(Axis current, Axis to_append) {
std::uint_fast16_t flag = static_cast<std::uint_fast16_t>(current);
flag = (flag << 2) | static_cast<std::uint_fast16_t>(to_append);
return static_cast<Axis>(flag);
}
template <class ... T>
Axis make_flag(T ... axes) {
std::array values = { axes... };
auto flag = values[0];
for (std::size_t i = 1; i < values.size(); ++i) {
flag = append_flag(flag, values[i]);
}
return flag;
}
int main(int argc, const char* argv[]) {
auto result = make_flag(Axis::X, Axis::Y, Axis::Z);
auto value = static_cast<std::size_t>(result);
std::cout << value << " (" << std::bitset<16>(value) << ")" << std::endl;
return 0;
}https://stackoverflow.com/questions/72159133
复制相似问题