sinad - 3 months ago 15

C++ Question

This is a really minimalist example. I'm using **Boost.Units** in the following way:

`#define REAL double`

...

using namespace boost::units;

quantity<si::velocity, REAL> v;

then sometimes I need to have something like

`quantity<si::velocity, REAL> v_halved;`

v_halved = 0.5 * v;

This works ok, because the compiler treats

`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&)

Looking into the

`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);

Although it is clear from the definition that the scalar and the internal type of the quantity must be the same, I would expect that the compiler automatically converts the type when the conversion can be done implicitly (like from

`double`

`long double`

`long double f(long double const & ld)`

My problem is that I have used expressions like

`v_halved = 0.5 * v`

`REAL`

`long double`

`static_cast<REAL>(0.5)`

Thanks a lot in advance!

Answer

template functions are different that non template function. Compiler decide to select template function without considering the implicit casting/promotions. It just look for exact matching.

This is how C++ works in this area.

To get exact matching you would need such `operator *`

definition (notice this extra template param 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;
}
```

but I am afraid that will interfere with boost definition of `*`

. You can play with this - like define your own `quantity`

which will derive almost entirely from boost - but define multiplication in different way, proposed by me.

Just decide what is easier for you to go with

- do static cast (or better just add
`L`

-`0.5L`

to make long double constant) - or do some combinations with templates.