2013-02-06 13 views
7

Chcę użyć jednostek boost :: units dla niektórych danych SI. Jednak nasz kod głównie zajmuje się milimetrów i zamiast używaćMilimetry w boost :: jednostki

quantity<length> value = 1*milli*meter; 

wolelibyśmy coś

quantity<length> value = 1*millimeter; 

Jednak nie jestem pewien, jak zdefiniować „milimetr” (bez użycia #define).

Po drugie, jaki jest narzut w użyciu jednostek z prefiksem?

Aktualizacja: To musi działać bez C++ 11 funkcji (tzn bez UDL)

Odpowiedz

4

Używam następujące podejście:

// your namespace name for units 
namespace outernamespace { 
    namespace millimeter_system { 
     typedef boost::units::scaled_base_unit<boost::units::si::meter_base_unit, boost::units::scale<10, boost::units::static_rational<-3>>> millimeter_base_unit; 

     typedef boost::units::make_system<millimeter_base_unit>::type system; 
     typedef boost::units::unit<boost::units::length_dimension, system> length; 

     BOOST_UNITS_STATIC_CONSTANT(millimeter, length); 
     BOOST_UNITS_STATIC_CONSTANT(millimeters, length); 
    } 

    typedef boost::units::quantity<millimeter_system::length> quantity_millimeter; 
    using millimeter_system::millimeter; 
    using millimeter_system::millimeters; 
} 

// demonstration of usage 
void foo() { 
    using namespace outernamespace; 
    using namespace boost::units; 
    using namespace boost::units::si; 

    quantity_millimeter mm = 5 * millimeter; 
    quantity<boost::units::si::length> m = 0.004 * meter; 
    if (mm < static_cast<quantity_millimeter>(m)) { 
     std::cout << 'lt ' << std::endl; 
    } 
    else { 
     std::cout << 'geq ' << std::endl; 
    } 
} 
-2

Jeśli masz C++ 11 zdolny kompilator można użyć User Defined Literals definiowania jednostek.

double operator"" _millimeter (double value) 
{ 
    return value; 
} 

można wykorzystywać że tak:

double foo = 1000_millimeter; 
+6

Ale to nie jest „prawdziwe” milimetrów, ale tylko przyrostek załączeniu. To znaczy. cała funkcjonalność boost :: units zniknęła. Na przykład. konwersja między metrem/milimetr, wiedząc, że Obszar s = 1 * milimetr * 1 * milimetr jest poprawny, ale Obszar s = 1 * 5 nie jest prawidłowy. – Frankie

+0

Plus Potrzebuję czegoś, co nie używa UDL. – Frankie

+0

Ale można to łatwo połączyć z jednostkami boost, zwracając liczbę zamiast podwójnego – ooxi

11

C++ 11 rzeczywiście jest najprostszym rozwiązaniem. Można zrobić

static const auto millimeter = milli * meter; 

lub

auto operator"" _mm (long double val) -> decltype(val * milli * meter) 
{ 
    return val * milli * meter; 
} 

Nie powinno być kara wydajność tak długo, jak nie są konwersja do innych prefiksów. A nawet jeśli to zrobisz, powinno być zaniedbane.

Jeśli nie chcesz korzystać z C++ 11 trzeba by znaleźć się odpowiedni rodzaj ekspresji milli * meter, choć może po prostu zastąpić auto przez int i odczytać wiadomość kompilatora.

+0

Powinno to być 'long double val' (patrz http://pl.cppreference.com/w/cpp/language/user_literal) –

+0

Dzięki, poprawione :) – filmor

Powiązane problemy