Ora che abbiamo a breve definiti letterali definiti dall'utente (UDL), ad esempio in GCC 4.7, sto aspettando con ansia le librerie di unità (fisiche) (come Boost.Unità) che le usano per facilitare l'espressione di valori letterali come 1+3i
, 3m
, 3meter
o 13_meter
. Qualcuno ha scritto un'estensione a Boost.Unità utilizzando UDL che supporta questo comportamento?Physical Boost.Units User Defined Literals
risposta
Nessuno è uscito con tale estensione. Solo gcc (e forse IBM?) Ha UDL quindi potrebbe essere un po 'di tempo. Spero che un qualche tipo di unità lo trasformi in tr2, che sta iniziando ora. Se ciò accade, sono sicuro che l'UDL per le unità verrà fuori.
Questo funziona:
// ./bin/bin/g++ -std=c++0x -o units4 units4.cpp
#include <boost/units/unit.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/systems/si.hpp>
using namespace boost::units;
using namespace boost::units::si;
quantity<length, long double>
operator"" _m(long double x)
{ return x * meters; }
quantity<si::time, long double>
operator"" _s(long double x)
{ return x * seconds; }
int
main()
{
auto l = 66.6_m;
auto v = 2.5_m/6.6_s;
std::cout << "l = " << l << std::endl;
std::cout << "v = " << v << std::endl;
}
penso che non sarebbe troppo difficile per voi passare attraverso unità preferite e fare questo.
Per quanto riguarda il loro inserimento in una libreria: Gli operatori letterali sono funzioni di ambito dei nomi. La competizione per i suffissi diventerà brutta. Vorrei (se fossi spinta) hanno
namespace literals
{
...
}
Poi Boost gli utenti possono fare
using boost::units::literals;
insieme a tutti gli altri decls utilizzano in genere si usa. Ad esempio, non ti verrà impedito da std::tr2::units
. Allo stesso modo se fai girare il tuo.
Annoyance # 1: gli operatori letterali possono prendere solo alcuni tipi di argomenti. Sarebbe bello avere versioni che restituiscono float e double e anche double double in modo che i calcoli non vengano promossi fino a raddoppiare il tempo per tutto il tempo? ADL non selezionerà solo per tipo di ritorno, spazi dei nomi specifici di precisione e utilizzo? Ugh. – emsr
Annoyance # 2: oltre a tutte le unità, sarebbe bello avere almeno multipli comuni. per esempio. non solo "m" ma "km", "cm", "mm" per le lunghezze, "Hz", "kHz", "MHz", "GHz" per la frequenza. Potrebbe diventare noioso - o coinvolgere alcuni macro. – emsr
Mi chiedo perché la promozione di una precisione _ più alta è un problema per voi ... – celticminstrel
Secondo me non c'è molto vantaggio nell'usare i letterali per Boost.Units, perché una sintassi più potente può ancora essere raggiunta con le funzionalità esistenti.
In casi semplici, sembra letterale è la strada da percorrere, ma presto si vede che non è molto potente. Ad esempio, è ancora necessario definire i valori letterali per le unità combinate, ad esempio, come si esprime 1 m/s (un metro al secondo)?
Attualmente:
auto v = 1*si::meter/si::second; // yes, it is long
ma con letterali?
// fake code
using namespace boost::units::literals;
auto v = 1._m_over_s; // or 1._m/si::second; or 1._m/1_s // even worst
Una soluzione migliore può essere realizzato con le caratteristiche esistenti. E questo è quello che faccio:
namespace boost{namespace units{namespace si{ //excuse me!
namespace abbreviations{
static const length m = si::meter;
static const time s = si::second;
// ...
}
}}} // thank you!
using namespace si::abbreviations;
auto v = 1.*m/s;
Allo stesso modo si può fare: auto a = 1.*m/pow<2>(s);
o estendere le abbreviazioni più se si vuole (ad esempio static const area m2 = pow<2>(si::meter);
)
Che altro di là di questo cosa vuoi?
Forse una soluzione combinata potrebbe essere il modo
auto v = 1._m/s; // _m is literal, /s is from si::abbreviation combined with operator/
ma ci sarà tanto codice ridondante e il guadagno è minimo (sostituire *
dal _
dopo il numero.)
Uno svantaggio della mia soluzione è che lo spazio dei nomi viene polarizzato con nomi di una lettera comuni. Ma non vedo un modo per aggirare questo, se non per aggiungere un carattere di sottolineatura (all'inizio o alla fine della sigla), come in 1.*m_/s_
ma almeno posso creare espressioni di unità reali.
Considerando che l'unico compilatore con supporto UDL è GCC, e anche allora solo in una versione instabile, sto indovinando no. Inoltre, gli UDL che non iniziano con '_' sono riservati per gli standard futuri; non puoi scriverli da solo –
Questo è bello sapere! Mi chiedevo solo come UDL potesse entrare in conflitto con i suffissi letterali numerici attuali 'l',' f' e 'd'. Il requisito '_' risponde a questa domanda. –