我正在研究一个我想利用的软件设计Boost.Units
.我想使用的一些单元代表时间,但是,我倾向于使用C++ 11 std::chrono
单元,因为它们是标准的.
我想知道是否有任何干净的集成Boost.Units
,chrono
或者我是否必须通过在类型之间复制标量值来编写我自己的转换器并失去类型安全性.
这个问题有什么最佳做法吗?
我正在进行大量的科学编程,并使用Boost.Units提供了非常好的经验,它提供了数量的编译时尺寸分析(即带有单位的标签数量,从而通过经典物理尺寸分析捕获了许多误差)并使用了Eigen 2代表线性代数.
然而,Eigen没有单位的概念,虽然你可以在Eigen的矩阵中设置标量,但是它期望两个量的乘法产生相同的类型,这对于单位来说显然是不正确的.例如,代码如:
using boost::units::quantity;
namespace si = boost::units::si;
Eigen::Matrix< quantity< si::length >, 2, 1 > meter_vector;
quantity< si::area > norm = meter_vector.squaredNorm();
Run Code Online (Sandbox Code Playgroud)
不起作用,即使它在逻辑上是正确的.
有没有支持单位的矩阵库?我知道这在过去很难实现,而且C++ 11 decltype
会更容易实现,但是C++ 03和模板专业化肯定是可能的.
我需要从一般的angular_velocity转换为度/秒.
为了说明这个问题,示例boostUnits.cpp:
#include <boost/units/systems/si.hpp>
#include <boost/units/systems/angle/revolutions.hpp>
#include <boost/units/systems/angle/degrees.hpp>
#include <boost/units/conversion.hpp>
#include <boost/units/pow.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
boost::units::quantity< boost::units::si::angular_velocity> m_speed(
(30.0*boost::units::si::radians_per_second)
);
std::cout << "m_speed: " << m_speed << std::endl;
uint32_t result = static_cast<uint32_t>(
boost::units::quantity<boost::units::si::angular_velocity,uint32_t>(
m_speed*boost::units::degree::degrees/boost::units::si::seconds
).value()
);
std::cout << " result: "<< result << std::endl;
return(0);
}
Run Code Online (Sandbox Code Playgroud)
生成此编译器输出:
g++ boostUnits.cpp
/usr/local/include/boost/units/detail/conversion_impl.hpp: In static member function ‘static boost::units::quantity<Unit2, T2> boost::units::conversion_helper<boost::units::quantity<Unit1, T1>, boost::units::quantity<Unit2, T2> >::convert(const boost::units::quantity<Unit1, T1>&) [with Unit1 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x000000002l, 1l> >, boost::units::list<boost::units::dim<boost::units::plane_angle_base_dimension, boost::units::static_rational<2l, 1l> …
Run Code Online (Sandbox Code Playgroud) 我目前正在使用boost :: units来表示si单位的扭矩,但是我给出了英尺扭矩.我试图创造一个pound_foot单位的扭矩和转换来支持这一点.我的懒惰尝试只是简单地定义:
BOOST_STATIC_CONST(boost::si::torque, pound_feet = 1.3558179483314 * si::newton_meters);
Run Code Online (Sandbox Code Playgroud)
然后做:
boost::si::torque torque = some_value * pound_feet;
Run Code Online (Sandbox Code Playgroud)
但这感觉不尽如人意.我的第二次尝试是尝试定义一个名为pound_foot的新基本单元(见下文).但是当我尝试以类似于上面的方式使用它时(使用转换为si单元),我得到一个充满错误的页面.有关正确方法的任何建议吗?
namespace us {
struct pound_foot_base_unit : base_unit<pound_foot_base_unit, torque_dimension> { };
typedef units::make_system<
pound_foot_base_unit>::type us_system;
typedef unit<torque_dimension, us_system> torque;
BOOST_UNITS_STATIC_CONSTANT(pound_foot, torque);
BOOST_UNITS_STATIC_CONSTANT(pound_feet, torque);
}
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(us::torque,
boost::units::si::torque,
double, 1.3558179483314);
Run Code Online (Sandbox Code Playgroud) 我想对一些SI指标使用boost :: units.然而,我们的代码主要处理毫米而不是使用
quantity<length> value = 1*milli*meter;
Run Code Online (Sandbox Code Playgroud)
我们更喜欢像
quantity<length> value = 1*millimeter;
Run Code Online (Sandbox Code Playgroud)
但是我不确定如何定义"毫米"(不使用#define).
其次,使用前缀单位的开销是多少?
更新:这需要在没有C++ 11功能的情况下运行(即没有UDL)
现在,我们很快有用户定义的文本(UDL),在4.7 GCC例如,我热切地等待(物理)单元库(如Boost.Units使用它们来缓解文字如的表达)1+3i
,3m
,3meter
或13_meter
.是否有人使用支持此行为的UDL 编写了Boost.Units的扩展名?
从概念上讲,在我看来,使用基于单位强制执行的类型(Meters,Seconds,Kilograms)会有很大的好处(额外检查传递args,摆脱变量中的单位名称等)但我没有遇到过多少代码哪个.我见过的代码确实使用了自定义类型.
我看到boost有一个单元库(boost :: units就够了)然而,我没有看到它被广泛使用的广泛使用的证据(在基本的谷歌搜索中).
有这么好的理由吗?
这些似乎意味着必须有某种原因这种做法没有像我期望的那样被广泛采用.也许比某些原因值得更麻烦?
所以我问:
有没有理由不使用单位执行类型?特别是有理由不使用boost :: units吗?
我需要将数量的值传递给库进行评估.该压单元库发生在SI双重价值,所以压单元库是确保需求非常有吸引力.但是,我该如何将数量转换为双倍值?文档和示例似乎避免了这种情况,因为其意图是维护单元.
就像是:
quantity<pressure> p(101.1 * kilo * pascals);
double dblP = static_cast<double>(p); // double value in Pascals
Run Code Online (Sandbox Code Playgroud)
通过标题建议......这是投射到基类型的正确方法吗?
p.value();
Run Code Online (Sandbox Code Playgroud) 我正在尝试为米和公里创建单位.我想要总结并相应地转换它们.我知道boost :: units库已经有了SI系统,但我想从头开始创建,因为那时我需要为我的项目创建自己的系统(所以我这样做是为了学习).我的目的是声明一个可以使用单位修改的"长度"变量:例如我想写
Length xLength1 = 5350 * Meters + 2 Kilometers;
Run Code Online (Sandbox Code Playgroud)
为此,我创建了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"; } …
Run Code Online (Sandbox Code Playgroud) 我试图在项目中使用boost :: units但遇到了麻烦.
我有一个模板类,它有一些quantity
对象作为成员.在一个我希望存储一个压力维度的值,所以我已quantity<pressure> press;
声明为成员变量.
但是,这会产生一个错误,指出quantity
需要两个模板参数(源代码显示第二个模板参数应默认为double
).如果我然后指定quantity<pressure,double> press;
我而不是得到一个错误
我做错了什么或者压力的实施有问题吗?
最小例子:
#include <boost/units/dimension.hpp>
#include <boost/units/systems/si/pressure.hpp>
using namespace boost::units;
using namespace boost::units::si;
struct MyClass
{
quantity<pressure,double> press;
};
Run Code Online (Sandbox Code Playgroud)
细节:
我正在审查boost单元库,我很困惑为什么boost :: units :: unit类有一个额外的模板参数.这是一个例子:
http://www.boost.org/doc/libs/1_57_0/boost/units/unit.hpp
template<class Dim,class System, class Enable>
class unit
{
public:
typedef unit<Dim, System> unit_type;
typedef unit<Dim,System> this_type;
typedef Dim dimension_type;
typedef System system_type;
unit() { }
unit(const this_type&) { }
//~unit() { }
this_type& operator=(const this_type&) { return *this; }
// sun will ignore errors resulting from templates
// instantiated in the return type of a function.
// Make sure that we get an error anyway by putting.
// the check in the destructor.
#ifdef …
Run Code Online (Sandbox Code Playgroud) c++ templates generic-programming boost-units template-classes
如果我只想将一个值从一个单位转换为另一个单位,那么最简单(理想情况是一行)的方法是什么?
例如,我想以米为单位存储一个值,但以英里为单位指定.
大多数执行此操作的示例似乎是多行,涉及typedef和单位定义,并且不提供简单的无单位输出.
boost-units ×12
c++ ×12
boost ×10
templates ×2
c++-chrono ×1
c++11 ×1
eigen ×1
gcc ×1
types ×1