First, thanks for the most excellent boost::units library. We are making good use of it in a scientific software project. I confess that there more than a few things that remain mysterious to me, but I'll focus on one example here:
----------------------------------------------------------------
#include <iostream>
#include
#include
using namespace std;
using namespace boost::units;
/** @brief electron volts */
struct ev_base_unit :
public base_unit{
/** @brief Get the unit name */
static const char* name() { return "electron-Volt"; }
/** @brief Get the unit symbol */
static const char* symbol() { return "eV"; }
};
typedef ev_base_unit::unit_type ev_unit;
BOOST_UNITS_STATIC_CONSTANT(eV, ev_unit);
// keV
typedef make_scaled_unit > >::type kev_unit;
BOOST_UNITS_STATIC_CONSTANT(keV, kev_unit);
// can only define conversion from a base unit.
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(ev_base_unit, si::energy, double,
1.60217653e-19);
// without this, conversion from si::energy to eV doesn't work
BOOST_UNITS_DEFAULT_CONVERSION(ev_base_unit, si::energy);
int main(int argc, char **argv){
// "natural" direction (ev -> joule)
cerr << "conversion ev to joule: "
<< conversion_factor(eV, si::joule) << endl;
cerr << "conversion kev/s to joule/s: "
<< conversion_factor(keV/si::second, si::joule/si::second) << endl;
// "reverse" direction (joule -> ev)
cerr << "conversion joule to ev: "
<< conversion_factor(si::joule, eV) << endl;
cerr << "conversion from joule/s to kev/s: "
<< conversion_factor(si::joule/si::second, keV/si::second) << endl;
// eV to keV conversions
cerr << "conversion ev to kev: "
<< conversion_factor(eV, keV) << endl;
cerr << "conversion ev/s to kev/s: "
// Fails to compile:
<< conversion_factor(eV/si::second, keV/si::second)
<< endl;
return 0;
}
----------------------------------------------------------------
When compiling the program above with gcc 4.8.2 and boost 1.54, I get the error below. All the conversions for eV and keV to and from joules work fine (even when divided by time as a test), but going between eV/second and keV/second explodes. Is this a limitation of make_scaled_unit? I have also tried with scaled_base_unit, but the results are the same.
Thanks for any help,
Ben
In file included from /usr/include/boost/units/heterogeneous_system.hpp:39:0,
from /usr/include/boost/units/make_scaled_unit.hpp:15,
from test.cpp:3:
/usr/include/boost/units/detail/linear_algebra.hpp: In instantiation of ‘struct boost::units::detail::determine_extra_equations_skip_zeros_impl::apply, boost::units::list, boost::units::dimensionless_type> >, boost::units::dimensionless_type>, 1, 1, 3, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> > >’:
/usr/include/boost/units/detail/linear_algebra.hpp:259:54: required from ‘struct boost::units::detail::determine_extra_equations<2, false>::apply, boost::units::list, boost::units::dimensionless_type> >, boost::units::dimensionless_type>, 3, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> > >’
/usr/include/boost/units/detail/linear_algebra.hpp:264:17: required from ‘struct boost::units::detail::determine_extra_equations<3, false>::apply, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, 3, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> > >’
/usr/include/boost/units/detail/linear_algebra.hpp:538:13: required from ‘struct boost::units::detail::make_square_and_invert, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::list, boost::units::list, boost::units::list, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> > >’
/usr/include/boost/units/detail/linear_algebra.hpp:828:59: required from ‘struct boost::units::detail::normalize_units > >’
/usr/include/boost/units/detail/linear_algebra.hpp:1035:17: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/units/heterogeneous_system.hpp:243:93: required from ‘struct boost::units::detail::make_heterogeneous_system >, boost::units::dimensionless_type>, boost::units::homogeneous_system > > >’
/usr/include/boost/units/unit.hpp:93:7: required from ‘struct boost::units::reduce_unit >, boost::units::dimensionless_type>, boost::units::homogeneous_system > >, void> >’
/usr/include/boost/units/detail/conversion_impl.hpp:314:89: required from ‘struct boost::units::detail::conversion_impl<2>::apply >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::homogeneous_system > > >’
/usr/include/boost/units/detail/conversion_impl.hpp:445:13: required from ‘struct boost::units::detail::conversion_factor_helper >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, void>, boost::units::unit >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::list > >, boost::units::dimensionless_type> > >, void> >’
/usr/include/boost/units/conversion.hpp:176:1: required by substitution of ‘template typename boost::units::one_to_double_type::type>::type boost::units::conversion_factor(const FromUnit&, const ToUnit&) [with FromUnit = boost::units::unit >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, void>; ToUnit = boost::units::unit >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::list > >, boost::units::dimensionless_type> > >, void>]’
test.cpp:50:58: required from here
/usr/include/boost/units/detail/linear_algebra.hpp:197:48: error: no type named ‘item’ in ‘boost::units::list, boost::units::list, boost::units::dimensionless_type> >, boost::units::dimensionless_type>::next {aka struct boost::units::dimensionless_type}’
typedef typename RowsBegin::next::item next_row;
^
/usr/include/boost/units/detail/linear_algebra.hpp:199:39: error: no type named ‘item’ in ‘boost::units::list, boost::units::list, boost::units::dimensionless_type> >, boost::units::dimensionless_type>::next {aka struct boost::units::dimensionless_type}’
next_row::item::Numerator == 0,
^
/usr/include/boost/units/detail/linear_algebra.hpp:199:39: error: no type named ‘item’ in ‘boost::units::list, boost::units::list, boost::units::dimensionless_type> >, boost::units::dimensionless_type>::next {aka struct boost::units::dimensionless_type}’
/usr/include/boost/units/detail/linear_algebra.hpp: In instantiation of ‘struct boost::units::detail::calculate_base_unit_exponents_impl<false>::apply >, boost::units::list >, boost::units::dimensionless_type> >’:
/usr/include/boost/units/detail/linear_algebra.hpp:1051:122: required from ‘struct boost::units::detail::calculate_base_unit_exponents >, boost::units::list >, boost::units::dimensionless_type> >’
/usr/include/boost/units/heterogeneous_system.hpp:243:93: required from ‘struct boost::units::detail::make_heterogeneous_system >, boost::units::dimensionless_type>, boost::units::homogeneous_system > > >’
/usr/include/boost/units/unit.hpp:93:7: required from ‘struct boost::units::reduce_unit >, boost::units::dimensionless_type>, boost::units::homogeneous_system > >, void> >’
/usr/include/boost/units/detail/conversion_impl.hpp:314:89: required from ‘struct boost::units::detail::conversion_impl<2>::apply >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::homogeneous_system > > >’
/usr/include/boost/units/detail/conversion_impl.hpp:445:13: required from ‘struct boost::units::detail::conversion_factor_helper >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, void>, boost::units::unit >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::list > >, boost::units::dimensionless_type> > >, void> >’
/usr/include/boost/units/conversion.hpp:176:1: required by substitution of ‘template typename boost::units::one_to_double_type::type>::type boost::units::conversion_factor(const FromUnit&, const ToUnit&) [with FromUnit = boost::units::unit >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, void>; ToUnit = boost::units::unit >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::list >, boost::units::dimensionless_type> >, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::list > >, boost::units::dimensionless_type> > >, void>]’
test.cpp:50:58: required from here
/usr/include/boost/units/detail/linear_algebra.hpp:1045:96: error: could not convert template argument ‘boost::units::detail::normalize_units > >::extra’ to ‘int’
typedef typename strip_zeroes_impl::template apply<units>::type type;
^
test.cpp: In function ‘int main(int, char**)’:
test.cpp:50:58: error: no matching function for call to ‘conversion_factor(boost::units::divide_typeof_helper >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::dimensionless_type>, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, void>, boost::units::unit >, boost::units::dimensionless_type>, boost::units::homogeneous_system > >, boost::units::list > > > > > > > > > > >::type, boost::units::divide_typeof_helper >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system >, boost::units::dimensionless_type>, boost::units::list >, boost::units::list >, boost::units::list >, boost::units::dimensionless_type> > >, boost::units::list > >, boost::units::dimensionless_type> > >, void>, boost::units::unit >, boost::units::dimensionless_type>, boost::units::homogeneous_system > >, boost::units::list > > > > > > > > > > >::type)’
<< conversion_factor(eV/si::second, keV/si::second)
^
test.cpp:50:58: note: candidate is:
In file included from /usr/include/boost/units/quantity.hpp:29:0,
from /usr/include/boost/units/systems/si.hpp:19,
from test.cpp:4:
/usr/include/boost/units/conversion.hpp:176:1: note: template typename boost::units::one_to_double_type::type>::type boost::units::conversion_factor(const FromUnit&, const ToUnit&)
conversion_factor(const FromUnit&,const ToUnit&)
^
/usr/include/boost/units/conversion.hpp:176:1: note: substitution of deduced template arguments resulted in errors seen above