I am trying to create a set of units to use in a library, but I having trouble getting IO to work for some of them. Here is a simple example that demonstrates the problem. ============================ #include<iostream> #include <boost/units/systems/si.hpp> #include <boost/units/systems/si/io.hpp> using namespace boost::units; // short hand for meter namespace t { typedef si::length m; } namespace i { BOOST_UNITS_STATIC_CONSTANT( m, t::m ); } // centimeter namespace t { typedef make_scaled_unit< si::length, scale< 10, static_rational<-2> > >::type cm; } namespace i { BOOST_UNITS_STATIC_CONSTANT( cm, t::cm ); } // meter squared namespace t { typedef multiply_typeof_helper< m, m>::type m_m; } namespace i { BOOST_UNITS_STATIC_CONSTANT( m_m, t::m_m ); } // centimeter squared namespace t { typedef multiply_typeof_helper< cm, cm>::type cm_cm; } namespace i { BOOST_UNITS_STATIC_CONSTANT( cm_cm, t::cm_cm ); } // meter centimeter namespace t { typedef multiply_typeof_helper< m, cm>::type m_cm; } namespace i { BOOST_UNITS_STATIC_CONSTANT( m_cm, t::m_cm ); } // override default output, which prints "c(m^2)" namespace boost { namespace units { inline std::string name_string(const t::m_cm&) { return "meter centimeter"; } inline std::string symbol_string(const t::m_cm&) { return "m cm"; } } } // trying to overload output for centimeter squared namespace boost { namespace units { inline std::string name_string(const t::cm_cm&) { return "centimeter squared"; } inline std::string symbol_string(const t::cm_cm&) { return "cm^2"; } } } int main(int argc, char *argv[]) { std::cout << i::m << std::endl; std::cout << i::cm << std::endl; std::cout << i::m_m << std::endl; std::cout << i::m_cm << std::endl; //std::cout << i::cm_cm << std::endl; // this won't compile quantity<t::m_m> a1(100*i::cm_cm); std::cout << a1<< std::endl; // should be 0.01 m^2 quantity<t::m_m> a2(100*i::m_cm); std::cout << a2<< std::endl; // should be 1 m^2 return 0; } ============================ Basically, I am just trying to create a convenient set of short hands. Unit types are put in a 't' namespace and instances are put in a 'i' namespace with the same name. This works fine for doing calculations and conversions with the units, but I am having trouble with getting output to work for some of them. In the example above I create a centimeter unit by scaling the meter. Then I create three different area units with the product_typeof_helper struct: meter squared, meter centimeter, and centimeter squared. Conversions work for all three of these, but output will not work for the centimeter squared unit. The program above outputs m cm m^2 m cm 0.01 m^2 1 m^2 If I uncomment the line that tries to print i::cm_cm it won't compile. I get an error that says 'symbol' is not a member of ... and points at a line that says str += Begin::item::symbol() I can't understand why it doesn't work for a product of two scaled units. cdclark _______________________________________________ Boost-users mailing list [hidden email] https://lists.boost.org/mailman/listinfo.cgi/boost-users |
AMDG
On 10/04/2017 07:58 PM, CD Clark via Boost-users wrote: > <snip> > // centimeter > namespace t { typedef make_scaled_unit< si::length, scale< 10, > static_rational<-2> > >::type cm; } > namespace i { BOOST_UNITS_STATIC_CONSTANT( cm, t::cm ); } > > <snip> > > // centimeter squared > namespace t { typedef multiply_typeof_helper< cm, cm>::type cm_cm; } > namespace i { BOOST_UNITS_STATIC_CONSTANT( cm_cm, t::cm_cm ); } > > <snip> > //std::cout << i::cm_cm << std::endl; // this won't compile > > <snip> > If I uncomment the line that tries to print i::cm_cm it won't compile. I > get an error that says > > 'symbol' is not a member of ... > > and points at a line that says > > str += Begin::item::symbol() > > I can't understand why it doesn't work for a product of two scaled units. > The reason that it fails is that the output code instantiates the default implementation even if you override it. The problem is that there is no symbol defined for 10^-4. In Christ, Steven Watanabe _______________________________________________ Boost-users mailing list [hidden email] https://lists.boost.org/mailman/listinfo.cgi/boost-users |
> The reason that it fails is that the output code > instantiates the default implementation even if > you override it. The problem is that there is > no symbol defined for 10^-4. Ah, that explains why it works for millimeter. Multiplying two millimeter units together gives 10^-6, which has a symbol. Does this mean that the IO can't handle units that have base units raised to some power that does not correspond to a symbol, or is this just supposed to be done a different way? Looking at the libraries definition of farad (which contains seconds to the fourth power), a derived dimension is defined for capacitance, and then an a unit for that dimension is created. Should I be creating the centimeter squared unit from the area dimension directly instead of trying to build it from already defined units? Thanks you for the help. cdclark _______________________________________________ Boost-users mailing list [hidden email] https://lists.boost.org/mailman/listinfo.cgi/boost-users |
AMDG
On 10/05/2017 12:44 PM, CD Clark via Boost-users wrote: >> The reason that it fails is that the output code >> instantiates the default implementation even if >> you override it. The problem is that there is >> no symbol defined for 10^-4. > > Ah, that explains why it works for millimeter. Multiplying two millimeter > units together gives 10^-6, which has a symbol. Does this mean that the IO > can't handle units that have base units raised to some power that does not > correspond to a symbol, or is this just supposed to be done a different way? > > Looking at the libraries definition of farad (which contains seconds to the > fourth power), a derived dimension is defined for capacitance, and then an > a unit for that dimension is created. Should I be creating the centimeter > squared unit from the area dimension directly instead of trying to build it > from already defined units? > Based on the way you're using this, I would recommend, setting up the scaling at the base unit level, instead of scaling the whole unit: namespace t { using cm = scaled_base_unit< si::meter_base_unit, scale<10, static_rational<-2> > >::unit_type; } This should make the output work the way you want automatically, as it causes cm*cm to be represented as (cm)^2 instead of (c^2)(m^2). In Christ, Steven Watanabe _______________________________________________ Boost-users mailing list [hidden email] https://lists.boost.org/mailman/listinfo.cgi/boost-users |
That worked. Thank you.
cdclark _______________________________________________ Boost-users mailing list [hidden email] https://lists.boost.org/mailman/listinfo.cgi/boost-users |
Free forum by Nabble | Edit this page |