Próbuję utworzyć jednostki dla licznika i kilometra. Chcę następnie podsumować i odpowiednio je przekształcić. Wiem, że biblioteka boost :: units ma już system SI, ale chcę stworzyć wszystko od zera, ponieważ wtedy muszę stworzyć własne systemy dla moich projektów (więc robię to, aby się uczyć). Moim celem jest, aby zadeklarować zmienną „długość”, które mogą być modyfikowane za pomocą jednostek, na przykład: Chcę napisaćTworzenie konwersji zdefiniowanych przez użytkownika
Length xLength1 = 5350 * Meters + 2 Kilometers;
do tego celu, mam stworzył length.h plik zawierający definicje metr i kilometr, a na koniec Oświadczam konwersję pomiędzy tymi dwoma zespołami:
#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
Potem utworzyć plik units.h, w którym mogę zdefiniować mój własny system jednostkową
#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
Przynajmniej mogę używać tego nagłówka w moim głównej funkcji
#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;
}
Te projekty kompiluje, ale to nie to, co chcę. Kiedy drukuję zmienną x długość 2, otrzymuję 1500 m zamiast 1500 km lub 1500000 m. Suma też jest błędna, ponieważ obijam 1800 m. To tak, jakbym uważał kilometry za metry, a konwersja nie działa.
Co robię źle?
Definiujesz "Kilometr" tak, jak "Meter". Nie pamiętam z góry, jaki jest preferowany sposób definiowania "Kilometru" (być może istnieje inne makro), ale możesz spróbować czegoś takiego jak 'const Length Kilometry = 1000 * Meters;' (tasowanie kolejności definicji). –
Ale w tym przypadku nie mogę pisać i przyjmować wartości w kilometrach, ale tylko w metrach. Chcę mieć możliwość pracy z obydwoma jednostkami i używać obu wartości w razie potrzeby. – Jepessen
Po prostu w heads-upie, jeśli używasz MSVC++ lub gcc, możesz zastąpić strażnik '#DEFDEF LENGTH_H_' itd.' #pragma once' na górze każdego nagłówka. –