gpt4 book ai didi

c++ - 用户定义的类型 - 单位、转换

转载 作者:行者123 更新时间:2023-11-30 05:08:41 28 4
gpt4 key购买 nike

我正在尝试创建一些用户定义的类型来表示单位,以便我可以强类型化函数参数。例如,长度为毫米,速度为毫米每秒,加速度为毫米每秒等。

到目前为止我已经这样做了:

template<typename T, typename mksUnit>
struct Value
{
// data member
T val;

// constructor
constexpr explicit Value(T d) : val(d) {}

// operator overloads
Value & operator +=(const Value &rhs) { val += rhs.val; return *this; }
// other math and compare
// operators, etc.
}

template<int meters, int kilo, int seconds>
struct mksUnit
{
enum { m = meters, k = kilo, s = seconds };
};

有了它,我可以做如下事情:

using meters = Value<double, mksUnit<1, 0, 0>>;
using mm = Value<double, mksUnit<-3, 0, 0>>;
constexpr mm operator""_mm(long double v) { return mm(static_cast<double>(v)); }
using mmpersec = Value<double, mksUnit<-3, 0, 1>>;
constexpr mmpersec operator""_mms(long double v) { return mmpersec(static_cast<double>(v)); }
using mmpersec2 = Value<double, mksUnit<-3, 0, 2>>;
constexpr mmpersec2 operator""_mms2(long double v) { return mmpersec2(static_cast<double>(v)); }

创建我可以使用的单元:

mm dist = 5.5_mm;
mm dist1 = dist + 10_mm;
mmpersec velocity = mmpersec(50.0);
mmpersec2 accel = 100.0_mms2;

void set_accel(mmpersec2 accel) { _accel = accel; }

等等

我需要在某些类型之间进行转换,我正在寻找一种好的方法来完成它。我唯一的想法是从类继承并将类型重载添加到派生类。

struct millimeters: public mm
{
operator(meters) { return mm.val / 1000; }
}

或类似的东西。

我想做这样的事情:

meters len = meters(5.0);
len += millimeters(25);

例如,应该将 len 设置为 1.025。

我的问题是在如上所示派生的不同用户定义类型之间添加转换的最佳方法是什么。

最佳答案

我认为您从错误的方向解决问题。您不想转换任意单位,而是转换数量内的单位。

所以我会这样开始:

struct Quantity {
double value;
};

// Base Quantites
class Length : public Quantity {};
class Duration : public Quantity {};

// Base units
Length Meter() {
Length l;
l.value = 1;
return l;
}

Length Millimeter() {
Length l;
l.value = 0.001;
return l;
}

Duration Seconds() {
Duration t;
t.value = 1;
return t;
}

现在我们整理好了数量,可以开始转换了:

// It is a good Idea to use SFINAE here to enable this function
// only for derived classes of Quantity
template <class Quantity>
double transform(Quantity&& value, Quantity&& ratio) {
return value.value / ratio.value;
}

派生单位部分比较棘手:

template <class Q1, class Q2>
struct MultipliedQuantiy : public Quantity {};

// I would use SFINAE here too because it is a bad idea to
// define a multiplication for all possible types.
template <class Q1, class Q2>
auto operator*(Q1 q1, Q2 q2) {
MultipliedQuantiy<Q1, Q2> q;
q.value = q1.value * q2.value;
return q;
}

作为例子,我们可以使用这个:

auto area = 1000.0*Millimeter()*(1000.0*Millimeter());
auto squareMeter = 1.0*Meter()*Meter();
double area_in_m2 = transform(area, squareMeter);

所以这是关于如何完成的基本思想。实现其余操作取决于您。您还可以在很多地方使用 constexpr 来强制进行编译时评估。

关于c++ - 用户定义的类型 - 单位、转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46700294/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com