这不是我第一次打它。这次我在玩“二进制角度”类(无符号整数映射到0-360deg或0-180deg圆)。不同的对象跨越不同的范围。有时候是0-360,有些物体的角度是-180-+180。我希望将对象转换为度或弧度的“算术”值时自动完成。 我将“ span”的类型存储为该类的枚举属性,并且可以正常工作,但是我认为这是错误的。应该有静态测试该模板参数的方法。
我知道如何使用“ is_arithmetic”,“ is_unsigned”等静态检查。但是我找不到我想要的东西。
枚举声明:
enum cycle {
FULL, ///< 0 to 360deg
HALF, ///< 0 to 180deg
FULL_SYMMETRIC, ///< -180deg to 180deg
HALF_SYMMETRIC ///< -90deg to 90deg
};
类声明:
/// Binary angle representation with conversion to/from DEG and RAD
template<typename U = uint32_t, enum cycle c = FULL>
class angle {
U bin_angle;
static const enum cycle type = c;
public:
以及度数/弧度提取成员函数
/// Get current value in degrees or, optionally, in radians represented
/// by the floating point type D
template<typename D>
D get(enum angle_units au = DEG) const {
static_assert(std::is_arithmetic<D>::value,
"The angle can only be requested as an arithmetic type");
D circle_ang = cycle_span<D>(type);
D ang = D(0);
if (bin_angle != U(0)) {
// XXX there must be a better way than to use long double
long double ratio =
(long double) (maxU()) / (long double) (bin_angle);
ang = (circle_ang) / D(ratio);
}
if (ang > cycle_end<D>(type)) {
ang -= circle_ang;
}
if (au == RAD) {
ang = deg2rad<D>(ang);
}
return ang;
}
还有更好的方法吗?
答案 0 :(得分:0)
迈克尔·肯泽尔(Michael Kenzel)是对的-那是那些“大ah”时刻之一。代码已更改为
// Binary angle representation with conversion to/from DEG and RAD
template<typename U = uint32_t, enum cycle span = FULL>
class angle {
U bin_angle;
public:
和
/// Get current value in degrees or, optionally, in radians represented
/// by the floating point type D
template<typename D>
D get(enum angle_units au = DEG) const {
static_assert(std::is_arithmetic<D>::value,
"The angle can only be requested as an arithmetic type");
D circle_ang = cycle_span<D>(span);
D ang = D(0);
if (bin_angle != U(0)) {
// XXX there must be a better way than to use long double
long double ratio =
(long double) (maxU<U>()) / (long double) (bin_angle);
ang = (circle_ang) / D(ratio);
}
if (ang > cycle_end<D>(span)) {
ang -= circle_ang;
}
if (au == RAD) {
ang = deg2rad<D>(ang);
}
return ang;
}
,它就像以前一样工作。我什至没有想到template参数可以用作属性或变量。