【问题标题】:multiplying a scalar by a boost.units.quantity (automatic type conversion issues?)将标量乘以 boost.units.quantity(自动类型转换问题?)
【发布时间】:2012-10-15 20:07:45
【问题描述】:

这是一个非常简约的例子。我通过以下方式使用 Boost.Units

#define REAL double
...
using namespace boost::units;
quantity<si::velocity, REAL> v;

那么有时我需要类似的东西

quantity<si::velocity, REAL> v_halved;
v_halved = 0.5 * v;

这没问题,因为编译器将0.5 视为double。但是,当 REAL 有所不同时,我会收到编译错误,例如如果我将REAL 的定义更改为long double,编译会报错:

error: no match for ‘operator*’ in ‘5.0e-1 * v’
/usr/include/boost/units/detail/one.hpp:58: note: candidates are: boost::units::one boost::units::operator*(const boost::units::one&, const boost::units::one&)

查看 Boost.Units documentation 我发现operator* 重载如下:

// runtime scalar times quantity 
template<typename Unit, typename X> 
  multiply_typeof_helper< X, quantity< Unit, X > >::type 
  operator*(const X & lhs, const quantity< Unit, X > & rhs);

虽然从定义中可以清楚地看出量的标量和内部类型必须相同,但我希望编译器在可以隐式完成转换时自动转换类型(例如从double到@ 987654333@)。但是我认为我可能会遗漏一些东西,因为自动类型转换当然适用于其他简单的功能,如long double f(long double const &amp; ld)

我的问题是我经常使用像v_halved = 0.5 * v 这样的表达式,而我的项目已经变得相当大,直到现在,在将REAL 定义为long double 之后,我才意识到这是一个问题。所以,我想知道一个解决方法/解决方案,我知道static_cast&lt;REAL&gt;(0.5) 将是一个解决方案,但我仍然觉得我错过了一些关于编译器无法自动将标量转换为正确的东西输入。

提前非常感谢!

【问题讨论】:

    标签: c++ boost boost-units


    【解决方案1】:

    模板函数与非模板函数不同。编译器决定选择模板函数而不考虑隐式转换/提升。它只是寻找精确匹配。

    这就是 C++ 在这个领域的工作方式。

    要获得精确匹配,您需要这样的 operator * 定义(注意这个额外的模板参数 Y):

    template<typename Unit, typename X, typename Y> 
      typename multiply_typeof_helper< X, quantity< Unit, X > >::type 
      inline operator*(const Y & lhs, const quantity< Unit, X > & rhs)
    {
        return static_cast<X>(lhs) * rhs;
    }
    

    但我担心这会干扰* 的提升定义。你可以玩这个——比如定义你自己的quantity,它几乎完全来自boost——但是以不同的方式定义乘法,这是我提出的。

    只要决定什么对你来说更容易去

    • 进行静态转换(或者最好添加 L - 0.5L 以使 long double 常量)
    • 或与模板进行一些组合。

    【讨论】:

    • 如果在这种情况下编译器寻找完全匹配,那么这就解释了问题。正如您所提到的,添加 operator* 的新定义可能会干扰原始定义,因此这可能是库作者的决定。然后我想我会坚持使用static_cast&lt;REAL&gt; 解决方案,因为使用0.5L 将是特定于类型的。
    猜你喜欢
    • 1970-01-01
    • 2011-11-17
    • 2013-05-15
    • 1970-01-01
    • 2012-10-01
    • 2010-12-29
    相关资源
    最近更新 更多