【问题标题】:Creating user-defined conversions创建用户定义的转换
【发布时间】:2012-07-18 12:25:24
【问题描述】:

我正在尝试为米和公里创建单位。然后我想总结并相应地转换它们。我知道 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 m。这就像我将公里视为米,转换不起作用。

我做错了什么?

【问题讨论】:

  • 您将Kilometer 定义为与Meter 相同。我不记得定义Kilometer 的首选方法是什么(也许有不同的宏),但你可以尝试const Length Kilometer = 1000 * Meters; 之类的方法(打乱定义的顺序)。
  • 但在这种情况下,我不能以公里为单位写入和取值,而只能以米为单位。我希望能够同时使用这两个单位,并在需要时使用这两个值。
  • 显然你想要的是一种“变体”类型的提升量。这里有一些线索:boost.2283326.n4.nabble.com/…
  • 你“有”使用boost吗? C++ 中有更简单的方法可以做到这一点。 :)

标签: c++ boost boost-units


【解决方案1】:

除非您的项目是复制 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,可能是克、米、秒、开尔文等。

【讨论】:

  • 这不是 Boost.Units 方式,因此无法回答问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多