6

メートルとキロメートルの単位を作成しようとしています。次に、それらを合計してそれに応じて変換したいと思います。boost::units ライブラリには既に SI システムがあることはわかっていますが、プロジェクト用に独自のシステムを作成する必要があるため、すべてをゼロから作成したいと考えています (学習のためにこれを行っています)。私の目的は、単位を使用して変更できる「長さ」変数を宣言することです。たとえば、次のように記述します

Length xLength1 = 5350 * Meters + 2 Kilometers;

この目的のために、メートルとキロメートルの定義を含むlength.hファイルを作成し、最後にこれら 2 つの単位間の変換を宣言します。

#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 kmまたは1500000 mではなく1500 mが得られます。私は1800メートルを観察しているので、合計も間違っています。キロメートルをメートルと見なし、変換が機能しないようです。

私が間違っていることは何ですか?

4

1 に答える 1

0

Boost ライブラリを複製するプロジェクトでない限り、これは単位系をコーディングする非常識な方法のように思えます。テンプレートのハッキングが最良の選択肢になることはめったにありません。

代わりに、クラスを使用してください。以下の実際のコードではありません:

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

など、必要な単位への変換を実装します。基本的に、すべてが保存されている基本単位を選択し、それとの間で変換します。SI を行っている場合は、おそらくグラム、メートル、秒、ケルビンなどです。

于 2012-11-15T03:42:23.870 に答える