I'm trying to create units for meter and kilometer. I want then to sum and convert them accordingly. I know that the boost::units library has already SI system, but I want create all from scratch, because then I need to create my own systems for my projects (so I'm doing this to learn). My purpose is to declare a "Length" variable that can be modified using units: for example I want to write
Length xLength1 = 5350 * Meters + 2 Kilometers;
For this purpose, I've created the length.h file, containing definitions of meter and kilometer, and at the end I declare the conversion between these two units:
#ifndef LENGTH_H_
#define LENGTH_H_
#include <boost/units/base_dimension.hpp>
#include <boost/units/base_unit.hpp>
#include <boost/units/scaled_base_unit.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/conversion.hpp>
struct LengthBaseDimension : boost::units::base_dimension<LengthBaseDimension,1>{};
typedef LengthBaseDimension::dimension_type LengthDimension;
struct MeterBaseUnit : boost::units::base_unit<MeterBaseUnit, LengthDimension, 1>{};
template <> struct boost::units::base_unit_info<MeterBaseUnit>
{
static std::string name() { return "meter"; }
static std::string symbol() { return "m"; }
};
struct KilometerBaseUnit : boost::units::base_unit<KilometerBaseUnit, LengthDimension, 2>{};
template <> struct boost::units::base_unit_info<KilometerBaseUnit>
{
static std::string name() { return "kilometer"; }
static std::string symbol() { return "km"; }
};
// I don't want to use scaled_unit because I need this for my real purpose
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(KilometerBaseUnit, MeterBaseUnit, double, 1000.0);
#endif
Then I create the file units.h in which I define my own unit system
#ifndef LIB_UNITS_H_
#define LIB_UNITS_H_
#include "length.h"
#include <boost/units/unit.hpp>
#include <boost/units/static_constant.hpp>
#include <boost/units/make_system.hpp>
#include <boost/units/io.hpp>
typedef boost::units::make_system<MeterBaseUnit>::type UnitsSystem;
typedef boost::units::unit<boost::units::dimensionless_type, UnitsSystem> Dimensionless;
typedef boost::units::unit<LengthDimension , UnitsSystem> SystemLength;
BOOST_UNITS_STATIC_CONSTANT(Kilometer , SystemLength);
BOOST_UNITS_STATIC_CONSTANT(Kilometers , SystemLength);
BOOST_UNITS_STATIC_CONSTANT(Meter , SystemLength);
BOOST_UNITS_STATIC_CONSTANT(Meters , SystemLength);
// Typedefs of dimensions
typedef boost::units::quantity<SystemLength> Length;
#endif
At least, I use this header in my main function
#include "units.h"
#include <iostream>
int main(void)
{
Length xLength1 ( 300.0 * Meters);
Length xLength2 (1500.0 * Kilometer );
Length xLength3;
std::cout << xLength2 << std::endl;
xLength3 = xLength1 + xLength2;
return 0;
}
This projects compiles, but It does not do what I want. When I print the variable xLength2, I obtain 1500 m instead of 1500 km or 1500000 m. The sum is also wrong, because I obrain 1800 m. It's like I consider kilometers as meters and conversion does not work.
What I'm doing wrong?
Kilometer
to be the same asMeter
. I don't recall offhand what is the preferred way to defineKilometer
(perhaps there is a different macro), but you can try something likeconst Length Kilometer = 1000 * Meters;
(shuffling the order of definitions). – Commonplace#IFDEF LENGTH_H_
etc guards with#pragma once
at the top of each header. – Jollification