Using user defined literals with boost units

  boost, boost-units, c++

I’m trying to use user defined literals for imperial units in boost units. The implementation I have works fine for SI units but fails to compile with anything else I’ve tried.

This works fine since boost/units/systems/si.hpp is defined

using LengthMeters = boost::units::quantity<boost::units::unit<boost::units::length_dimension, boost::units::si::system>>;

auto operator"" _meters(long double val) -> decltype(val * boost::units::si::meter)
{
    return val * boost::units::si::meter;
}

LengthMeters my_meter{ 1.234_meters }; 

This is what I’m trying to do

Since there is no "boost/units/systems/imperial.hpp", I’m creating my own system.

// creating my own system for feet
namespace Imperial_System
{
    typedef boost::units::make_system<
        boost::units::imperial::foot_base_unit
    >::type system;
    typedef boost::units::unit<boost::units::dimensionless_type, system> dimensionless;
    typedef boost::units::unit<boost::units::length_dimension, system> length;
    static const length foot, feet;
}

using LengthFeet =   boost::units::quantity<boost::units::unit<boost::units::length_dimension, boost::units::imperial::foot_base_unit>>;

auto operator"" _feet(long double val) -> decltype(val * Imperial_System::foot)
{
    return val * Imperial_System::foot;
}

LengthFeet my_feet{ 1.234_feet };

This code fails to compile with too many errors to list here. Here are a few of them that I think could be important.

1>C:_____boostboostunitsunit.hpp(62,1): error C2664: 'int boost::mpl::assertion_failed<false>(boost::mpl::assert<false>::type)': cannot convert argument 1 from 'boost::mpl::failed ************boost::units::detail::check_system<System,Dim>::* ***********' to 'boost::mpl::assert<false>::type'
1>        with
1>        [
1>            System=boost::units::imperial::foot_base_unit,
1>            Dim=boost::units::length_dimension
1>        ]
> 1>C:_____boostboostunitsunit.hpp(62,1): message : No constructor could take the source type, or constructor overload resolution was ambiguous

Seeing this next error about yards makes me wonder if I need to add all of the imperial value types to my system. Adding yard also to my system still resulted in the same error.

1>C:_____boostboostunitsdetaillinear_algebra.hpp(654,23): error C2039: 'value': is not a member of 'boost::units::scaled_base_unit<boost::units::imperial::yard_base_unit,boost::units::scale<3,boost::units::static_rational<-1,1>>>'
1>C:_____boostboostunitsbase_unitsimperialfoot.hpp(25): message : see declaration of 'boost::units::scaled_base_unit<boost::units::imperial::yard_base_unit,boost::units::scale<3,boost::units::static_rational<-1,1>>>'
1>C:_____boostboostunitsdetaillinear_algebra.hpp(655,1): error C2975: 'N': invalid template argument for 'boost::units::detail::find_base_dimensions_impl', expected compile-time constant expression
1>C:_____boostboostunitsdetaillinear_algebra.hpp(631): message : see declaration of 'N'
1>C:_____boostboostunitsheterogeneous_system.hpp(245,67): error C3083: 'size': the symbol to the left of a '::' must be a type
1>C:_____boostboostunitsheterogeneous_system.hpp(245,73): error C2039: 'value': is not a member of 'boost::units::scaled_base_unit<boost::units::imperial::yard_base_unit,boost::units::scale<3,boost::units::static_rational<-1,1>>>'
1>C:_____boostboostunitsbase_unitsimperialfoot.hpp(25): message : see declaration of 'boost::units::scaled_base_unit<boost::units::imperial::yard_base_unit,boost::units::scale<3,boost::units::static_rational<-1,1>>>'
1>C:_____boostboostunitsheterogeneous_system.hpp(245,1): error C2975: 'N': invalid template argument for 'boost::units::detail::make_heterogeneous_system_impl', expected compile-time constant expression
1>C:_____boostboostunitsheterogeneous_system.hpp(214): message : see declaration of 'N'

Source: Windows Questions C++

LEAVE A COMMENT