How do I set the conversion factor for a user-defined Boost Unit?

113 views Asked by At

I am wanting to use Boost Units for a simulation, but there are a few units I need that aren't in the default systems. For example, slugs (mass). So I have created a custom slug unit that I can instantiate successfully as a quantity. However, when trying to set the conversion factor to kilograms, I get a compilation error.

Here is my header file test.h:

#ifndef DSHELL_TEST_SYSTEM_HPP
#define DSHELL_TEST_SYSTEM_HPP

#include <boost/units/base_dimension.hpp>
#include <boost/units/io.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/unit.hpp>
#include <boost/units/base_unit.hpp>
#include <boost/units/systems/si/mass.hpp>

using namespace boost::units;
using namespace boost::units::si;

namespace dshell {

namespace units {

    struct slug_base_unit : base_unit<slug_base_unit, mass_dimension, 1>
    {
        static std::string name()               { return "slug"; }
        static std::string symbol()             { return "sl"; }
    };

    typedef slug_base_unit::unit_type slug_unit;

    /// unit constants
    BOOST_UNITS_STATIC_CONSTANT(slug, slug_unit);
    BOOST_UNITS_STATIC_CONSTANT(slugs, slug_unit);

}
}

BOOST_UNITS_DEFINE_CONVERSION_FACTOR(dshell::units::slug_unit, boost::units::si::mass, double, 14.5939);

#endif // DSHELL_TEST_SYSTEM_HPP

And the main test.cc:

#include <iostream>

#include "test.h"

using namespace dshell::units;

int main () {
    quantity<slug_unit> A = 10.0 * slugs;
    quantity<mass> B = static_cast<quantity<mass> >(2.0 * slugs);
    quantity<mass> C = 2.0 * kilograms;
    quantity<mass> D = static_cast<quantity<mass> >(A);

    std::cout << A << std::endl;
    std::cout << B << std::endl;
    std::cout << C << std::endl;
    std::cout << D << std::endl;
}

This is the compilation error I get:

In file included from /usr/include/boost/units/conversion.hpp:14,
             from /usr/include/boost/units/quantity.hpp:29,
             from /usr/include/boost/units/io.hpp:28,
             from test.h:5,
             from test.cc:3:
/usr/include/boost/units/detail/conversion_impl.hpp: In instantiation of ‘boost::units::detail::call_base_unit_converter_base_unit_impl<false, false>::apply<dshell::units::slug_base_unit, boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > > >’:
/usr/include/boost/units/detail/conversion_impl.hpp:289:   instantiated from ‘boost::units::detail::call_base_unit_converter<dshell::units::slug_base_unit, boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void> >’
/usr/include/boost/units/detail/conversion_impl.hpp:316:   instantiated from ‘boost::units::detail::conversion_impl<1>::apply<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::dimensionless_type> > >’
/usr/include/boost/units/detail/conversion_impl.hpp:445:   instantiated from ‘boost::units::detail::conversion_factor_helper<boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void> >’
/usr/include/boost/units/detail/conversion_impl.hpp:40:   instantiated from ‘boost::units::detail::conversion_factor_helper<boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void> >’
/usr/include/boost/units/detail/conversion_impl.hpp:345:   instantiated from ‘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::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, T1 = double, Unit2 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>, T2 = double]’
/usr/include/boost/units/quantity.hpp:193:   instantiated from ‘boost::units::quantity<Unit, Y>::quantity(const boost::units::quantity<Unit2, YY>&, typename boost::disable_if<boost::mpl::and_<typename boost::units::is_implicitly_convertible<Unit2, Unit>::type, boost::units::detail::is_non_narrowing_conversion<YY, Y>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, typename boost::units::detail::disable_if_is_same<Unit, Unit2>::type>::type*) [with Unit2 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, YY = double, Unit = boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>, Y = double]’
test.cc:9:   instantiated from here
/usr/include/boost/units/detail/conversion_impl.hpp:202: error: no type named ‘type’ in ‘struct boost::units::detail::conversion_factor_helper<boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void> >’
/usr/include/boost/units/detail/conversion_impl.hpp:203: error: no type named ‘type’ in ‘struct boost::units::detail::conversion_factor_helper<boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void> >’
/usr/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::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, T1 = double, Unit2 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>, T2 = double]’:
/usr/include/boost/units/quantity.hpp:193:   instantiated from ‘boost::units::quantity<Unit, Y>::quantity(const boost::units::quantity<Unit2, YY>&, typename boost::disable_if<boost::mpl::and_<typename boost::units::is_implicitly_convertible<Unit2, Unit>::type, boost::units::detail::is_non_narrowing_conversion<YY, Y>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, typename boost::units::detail::disable_if_is_same<Unit, Unit2>::type>::type*) [with Unit2 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, YY = double, Unit = boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>, Y = double]’
test.cc:9:   instantiated from here
/usr/include/boost/units/detail/conversion_impl.hpp:345: error: no matching function for call to ‘conversion_factor(boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<dshell::units::slug_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>&, boost::units::unit<boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>&)’
0

There are 0 answers