我最近正在閱讀C++源代碼,「一個反映的停頓:五個列表五」的系列。在Part V中,Scott Meyers討論了Barton和Nackman解決單位問題的方法。作爲航空航天業的嵌入式軟件工程師,這個特別的Aha!時刻讓我興奮。到目前爲止,我還沒有聽說過這種方法(也沒有這些作者)。C++維度分析(巴恩斯和Nackman)與規模
我已經做了研究,試圖找到更多關於解決方案的信息。我在這裏遇到了這個演示文稿:http://se.ethz.ch/~meyer/publications/OTHERS/scott_meyers/dimensions.pdf
我想我理解了我在這個解決方案中讀到的所有內容。但我覺得缺少一塊難題。沒有這個美麗,優雅的解決方案地址的規模。具體而言,我對轉換不僅僅是一個倍增因素感興趣。例如,Kelvin,Celsius和Fahrenheit之間的溫度轉換。我希望能夠交替使用這些溫度。
我的問題:
我錯過了什麼?規模是否參考我忽略的單元解決方案討論進行討論?
如果不是,我怎麼能進一步處理這個問題?有沒有可以與B & N方法結合使用的現有模式來完成解決方案?
我的目標是能夠編碼,看起來像下面的例子,沒有過多的計算。在距離的情況下,我希望能夠聲明一個定義爲英里的對象,並執行所有我的相關計算,如同英里,而不必不斷地來回轉換爲米。
例子:
typedef Units<double, miles> uMiles;
typedef Units<double, kilometers> uKilometers;
uMiles d1 (1.0);
uKilometers d2 (1.60934);
d1 += d2;
if (d1.val(miles) == 2.0) // PASS
if (d1.val(kilometers) == 3.21869) // PASS
注: 我所見過的壓單元解決的問題,我不喜歡它。對我來說這是非常不可讀的。我也不是,通常被允許使用外部庫如boost。
備份數據:
的單位類描述:
template<class T, // Precision
int m, // Mass
int l, // Length
int t, // Time
int q, // Charge
int k, // Temperature
int i, // Luminous Intensity
int a> // Angle
class Units
{
public:
// ------------------------------------------------------
explicit
Units (T initVal = 0)
: val (initVal)
{
}
// --------------------------------------------------------------------
// Operator: Assignment from type T
Units<T, m, l, t, q, k, i, a>&
operator= (const T rhs)
{
val = rhs;
return *this;
}
// --------------------------------------------------------------------
// Operator: Type Converstion to T
operator T() const
{
return val;
}
// --------------------------------------------------------------------
// Operator: +=
Units<T, m, l, t, q, k, i, a>&
operator+= (const Units<T, m, l, t, q, k, i, a>& rhs)
{
val += rhs.val;
return *this;
}
// --------------------------------------------------------------------
Units<T, m, l, t, q, k, i, a>&
operator-= (const Units<T, m, l, t, q, k, i, a>& rhs)
{
val -= rhs.val;
return *this;
}
// --------------------------------------------------------------------
Units<T, m, l, t, q, k, i, a>&
operator*= (T rhs)
{
val *= rhs;
return *this;
}
// --------------------------------------------------------------------
Units<T, m, l, t, q, k, i, a>&
operator/= (T rhs)
{
val /= rhs;
return *this;
}
// --------------------------------------------------------------------
// Get Reference
T&
Val()
{
return val;
}
// --------------------------------------------------------------------
// Get Value
const T&
Val() const
{
return val;
}
private:
T val;
};
// ----------------------------------------------------------------------------
// Operator: Addition
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator+ (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result += rhs;
}
// ----------------------------------------------------------------------------
// Operator: Subtraction
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator- (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result -= rhs;
}
// ----------------------------------------------------------------------------
// Operator: Multiplication
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator* (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result *= rhs;
}
// ----------------------------------------------------------------------------
// Operator: Division
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator/ (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result /= rhs;
}
// ----------------------------------------------------------------------------
// Operator: Multiplication (Creates New Type)
template<class T,
int m1, int d1, int t1, int q1, int k1, int i1, int a1,
int m2, int d2, int t2, int q2, int k2, int i2, int a2>
// Return Type
Units<T, m1 + m2, d1 + d2, t1 + t2, q1 + q2, k1 + k2, i1 + i2, a1 + a2>
operator* (const Units<T, m1, d1, t1, q1, k1, i1, a1>& lhs,
const Units<T, m2, d2, t2, q2, k2, i2, a2>& rhs)
{
// New Return type
typedef Units<T,
m1 + m2,
d1 + d2,
t1 + t2,
q1 + q2,
k1 + k2,
i1 + i2,
a1 + a2> ResultType;
return ResultType (lhs.Val() * rhs.Val());
}
// ----------------------------------------------------------------------------
// Operator: Division (Creates New Type)
template<class T,
int m1, int d1, int t1, int q1, int k1, int i1, int a1,
int m2, int d2, int t2, int q2, int k2, int i2, int a2>
// Return Type
Units<T, m1 - m2, d1 - d2, t1 - t2, q1 - q2, k1 - k2, i1 - i2, a1 - a2>
operator/ (const Units<T, m1, d1, t1, q1, k1, i1, a1>& lhs,
const Units<T, m2, d2, t2, q2, k2, i2, a2>& rhs)
{
// New Return type
typedef Units<
T,
m1 - m2,
d1 - d2,
t1 - t2,
q1 - q2,
k1 - k2,
i1 - i2,
a1 - a2> ResultType;
return ResultType (lhs.Val()/rhs.Val());
}
這個類允許我們編寫的代碼看起來像這樣:
// Base Types
typedef Units<double, 1,0,0,0,0,0,0> uMass;
typedef Units<double, 0,1,0,0,0,0,0> uLength;
typedef Units<double, 0,0,1,0,0,0,0> uTime;
typedef Units<double, 0,0,0,1,0,0,0> uCharge;
typedef Units<double, 0,0,0,0,1,0,0> uTemperature;
typedef Units<double, 0,0,0,0,0,1,0> uIntensity;
typedef Units<double, 0,0,0,0,0,0,1> uAngle;
// Derived Types
typedef Units<double, 0,2, 0,0,0,0,0> uArea;
typedef Units<double, 0,3, 0,0,0,0,0> uVolume;
typedef Units<double, 0,1,-1,0,0,0,0> uVelocity;
typedef Units<double, 0,1,-2,0,0,0,0> uAcceleration;
typedef Units<double, 1,1,-2,0,0,0,0> uForce;
uMass mass;
uTime time;
uForce force;
uLength length;
uVelocity velocity;
uAcceleration acceleration;
// This will compile
mass = 7.2;
acceleration = 3.5;
force = mass * acceleration;
// These will not compile ** Enforcing Dimensional Unit Correctness
force = 7.2 * acceleration;
force = mass;
force *= acceleration;
我確實想要說明,我已經購買了Scott Meyers通過Barton和Nackman提及的那本書。我希望這本書能夠提供更多的見解。 http://www.amazon.com/Scientific-Engineering-Introduction-Advanced-Techniques/dp/0201533936/ref=sr_1_1?ie=UTF8&qid=1424790308&sr=8-1&keywords=Barton+Nackman – Jerunh 2015-02-24 15:05:42
單位是可以乘法組合的東西。度量標度不是(因爲它們有一個任意的零點,並不意味着「無」),所以我不希望有一個「單位」庫來處理它們。 – 2015-02-24 15:33:03
@MikeSeymour我不同意。所有單位都有隱含的規模。我只是尋找一種明確的方式,並提供一種轉換方式。提升單位也提供規模,雖然以一種醜陋的方式。 – Jerunh 2015-02-24 15:59:56