2012-07-19 89 views
5

我正在嘗試爲米和公里創建單位。然後我想要相應地總結和轉換它們。我知道boost :: units庫已經有了SI系統,但是我想從頭開始創建,因爲之後我需要爲我的項目創建自己的系統(所以我這樣做是爲了學習)。 我的目的是宣佈「長度」變量,可以使用單位進行修改:比如我想寫創建用戶定義的轉換

Length xLength1 = 5350 * Meters + 2 Kilometers; 

爲此,我創建了length.h文件,其中包含定義米和公里,並在最後,我宣佈這兩個單位之間的換算:

#ifndef LENGTH_H_ 
#define LENGTH_H_ 

#include <boost/units/base_dimension.hpp> 
#include <boost/units/base_unit.hpp> 
#include <boost/units/scaled_base_unit.hpp> 
#include <boost/units/quantity.hpp> 
#include <boost/units/conversion.hpp> 

struct LengthBaseDimension : boost::units::base_dimension<LengthBaseDimension,1>{}; 

typedef LengthBaseDimension::dimension_type LengthDimension; 

struct MeterBaseUnit : boost::units::base_unit<MeterBaseUnit, LengthDimension, 1>{}; 
template <> struct boost::units::base_unit_info<MeterBaseUnit> 
{ 
    static std::string name() { return "meter"; } 
    static std::string symbol() { return "m";  } 
}; 

struct KilometerBaseUnit : boost::units::base_unit<KilometerBaseUnit, LengthDimension, 2>{}; 
template <> struct boost::units::base_unit_info<KilometerBaseUnit> 
{ 
    static std::string name() { return "kilometer"; } 
    static std::string symbol() { return "km";  } 
}; 

// I don't want to use scaled_unit because I need this for my real purpose 
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(KilometerBaseUnit, MeterBaseUnit, double, 1000.0); 

#endif 

然後,我創建的文件,在其中units.h我定義自己的單元系統

#ifndef LIB_UNITS_H_ 
#define LIB_UNITS_H_ 

#include "length.h" 
#include <boost/units/unit.hpp> 
#include <boost/units/static_constant.hpp> 
#include <boost/units/make_system.hpp> 
#include <boost/units/io.hpp> 

typedef boost::units::make_system<MeterBaseUnit>::type UnitsSystem; 

typedef boost::units::unit<boost::units::dimensionless_type, UnitsSystem> Dimensionless; 
typedef boost::units::unit<LengthDimension     , UnitsSystem> SystemLength; 


BOOST_UNITS_STATIC_CONSTANT(Kilometer , SystemLength); 
BOOST_UNITS_STATIC_CONSTANT(Kilometers , SystemLength); 
BOOST_UNITS_STATIC_CONSTANT(Meter  , SystemLength); 
BOOST_UNITS_STATIC_CONSTANT(Meters  , SystemLength); 

// Typedefs of dimensions 
typedef boost::units::quantity<SystemLength> Length; 

#endif 

至少,我用這個頭在我的主要功能

#include "units.h" 
#include <iostream> 

int main(void) 
{ 
    Length xLength1 (300.0 * Meters); 
    Length xLength2 (1500.0 * Kilometer); 
    Length xLength3; 
    std::cout << xLength2 << std::endl; 
    xLength3 = xLength1 + xLength2; 

    return 0; 
} 

該項目的編譯,但它不會做我想做的。當我打印變量xLength2時,獲得1500 m而不是1500 km1500000 m。總和也是錯誤的,因爲我忽略了1800米。這就像我認爲公里爲米,轉換不起作用。

我在做什麼錯了?

+0

你定義'千米'與'米'相同。我不記得什麼是定義'公里數'(可能有不同的宏)'的首選方法,但你可以嘗試像'const Length Kilometer = 1000 * Meters'(混洗定義順序)。 – 2012-07-19 11:41:54

+1

但是在這種情況下,我不能以公里爲單位寫出價值,只能以米爲單位。我希望有可能與兩個單位合作,並在需要的地方使用兩個值。 – Jepessen 2012-07-19 17:16:36

+0

如果你正在使用MSVC++或gcc,你可以用每個頭頂部的#pragma once替換你的'#IFDEF LENGTH_H_'等警衛。 – 2012-08-09 13:57:11

回答

0

除非你的項目是複製Boost庫,否則這似乎是一個瘋狂的方式來編碼單位系統。模板hackery很少是最好的選擇。

相反,使用一個類!下面不是真實代碼:

class temperature{ 
    double temp; //always in kelvin 
    temperature(double temperature, char unit){ 
     if(unit=='k') 
       temp=temperature 
     if(unit=='c') 
       temp=temperature+273 
    } 
}; 

等等來實現轉換回你想要的任何單位。基本上你選擇一個基本單位,一切都存儲爲,並從中轉換。如果你在做SI,也許是克,米,秒,開爾文等。

+0

這不是Boost.Units方式,因此不回答問題。 – Ruslan 2016-02-10 14:05:59