[units] Creating a velocity unit

Boost Community, I'm trying to create a custom velocity unit. I would like to create a unit that is in nautical miles per hour to represent my speed value. If I use pound_force.hpp as an example of units with more than one dimension I can create the following. BOOST_UNITS_DEFINE_BASE_UNIT_WITH_CONVERSIONS(metric, nautical_mile_per_hour, "nautical mile per hour", "nmi h^-1", factor, si::velocity, ???); If this is the right track, what id would I use and how do I know that it is unique? This seems forced. I would rather define this unit in terms of meters per second. Nautical miles is already in terms of meters and hours is also defined as a scale of seconds. Can I somehow use these two already defined units to create the new unit? How would I do this? Ryan

AMDG On 02/20/2013 06:32 PM, Ryan wrote:
Boost Community,
I'm trying to create a custom velocity unit. I would like to create a unit that is in nautical miles per hour to represent my speed value. If I use pound_force.hpp as an example of units with more than one dimension I can create the following.
BOOST_UNITS_DEFINE_BASE_UNIT_WITH_CONVERSIONS(metric, nautical_mile_per_hour, "nautical mile per hour", "nmi h^-1", factor, si::velocity, ???);
If this is the right track, what id would I use and how do I know that it is unique?
This seems forced. I would rather define this unit in terms of meters per second. Nautical miles is already in terms of meters and hours is also defined as a scale of seconds. Can I somehow use these two already defined units to create the new unit? How would I do this?
You probably don't need to define a base unit. Just use: typedef decltype( nautical_mile_base_unit::unit_type() / hour_base_unit::unit_type()) nautical_miles_per_hour; In Christ, Steven Watanabe

I previously had a similar question where I had to define my own unit that
may be helpful to you:
http://stackoverflow.com/questions/4322133/converting-units-in-boost-units-f...
Cheers!
Andrew Hundt
On Wed, Feb 20, 2013 at 10:11 PM, Steven Watanabe
AMDG
Boost Community,
I'm trying to create a custom velocity unit. I would like to create a unit that is in nautical miles per hour to represent my speed value. If I use pound_force.hpp as an example of units with more than one dimension I can create the following.
BOOST_UNITS_DEFINE_BASE_UNIT_WITH_CONVERSIONS(metric, nautical_mile_per_hour, "nautical mile per hour", "nmi h^-1", factor, si::velocity, ???);
If this is the right track, what id would I use and how do I know that it is unique?
This seems forced. I would rather define this unit in terms of meters
On 02/20/2013 06:32 PM, Ryan wrote: per
second. Nautical miles is already in terms of meters and hours is also defined as a scale of seconds. Can I somehow use these two already defined units to create the new unit? How would I do this?
You probably don't need to define a base unit. Just use:
typedef decltype( nautical_mile_base_unit::unit_type() / hour_base_unit::unit_type()) nautical_miles_per_hour;
In Christ, Steven Watanabe _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Thanks for the link it was helpful. I tried both methods and they both
compiled. It seems we can use the simpler form of decltype because it
provides perfect forwarding. Is this a correct interpretation?
Neither of these two typedef seems to behave as I expected. When creating
a quantity with these typedefs I had to call them as a method to get the
code to compile.
quantitysi::velocity a(2.3 * nautical_miles_per_hour1());
quantitysi::velocity b(2.4 * nautical_miles_per_hour2());
quantitysi::velocity c(2.5 * si::meters_per_second);
Is there a way to get my type of nautical_miles_per_hour to behave like
meters_per_second?
Ryan
//Provided for the Discussion
using namespace boost::units;
typedef metric::nautical_mile_base_unit::unit_type nautical_mile_unit;
typedef metric::hour_base_unit::unit_type hour_unit;
typedef decltype(nautical_mile_unit() / hour_unit())
nautical_miles_per_hour1;
typedef divide_typeof_helper

AMDG On 02/21/2013 10:25 AM, Ryan wrote:
Thanks for the link it was helpful. I tried both methods and they both compiled. It seems we can use the simpler form of decltype because it provides perfect forwarding. Is this a correct interpretation?
Yes. The two are equivalent. decltype is a bit nicer, as long as you know that you'll only be using a compiler that supports it.
Neither of these two typedef seems to behave as I expected. When creating a quantity with these typedefs I had to call them as a method to get the code to compile.
quantitysi::velocity a(2.3 * nautical_miles_per_hour1()); quantitysi::velocity b(2.4 * nautical_miles_per_hour2()); quantitysi::velocity c(2.5 * si::meters_per_second);
Is there a way to get my type of nautical_miles_per_hour to behave like meters_per_second?
The difference is that meters_per_second is an object, not a type: static const si::velocity meters_per_second; At this point, I prefer to use the type, because I don't like having to come up with two different names for the type and the global constant. I suppose that it would also be possible to use only the object, and use decltype whenever you need a type.
//Provided for the Discussion using namespace boost::units; typedef metric::nautical_mile_base_unit::unit_type nautical_mile_unit; typedef metric::hour_base_unit::unit_type hour_unit;
typedef decltype(nautical_mile_unit() / hour_unit()) nautical_miles_per_hour1; typedef divide_typeof_helper
::type nautical_miles_per_hour2;
In Christ, Steven Watanabe

The difference is that meters_per_second is an object, not a type:
static const si::velocity meters_per_second;
I see.
At this point, I prefer to use the type, because I don't like having to come up with two different names for the type and the global constant.
That is a pain. I suppose that it would also be possible to use only the
object, and use decltype whenever you need a type.
I tried using the decltype to get the type but got an error. Is this how
you meant to use it?
typedef metric::nautical_mile_base_unit::unit_type nautical_mile_unit;
static const nautical_mile_unit nautical_mile;
quantity

AMDG On 02/21/2013 12:09 PM, Ryan wrote:
I suppose that it would also be possible to use only the object, and use decltype whenever you need a type.
I tried using the decltype to get the type but got an error. Is this how you meant to use it?
typedef metric::nautical_mile_base_unit::unit_type nautical_mile_unit; static const nautical_mile_unit nautical_mile;
quantity
(2.3 * nautical_mile);
Yes, that's what I meant, but now that I see it written out, it's wrong because decltype keeps the const qualifier. You need the behavior of the non-standard typeof operator. BOOST_TYPEOF should work. In Christ, Steven Watanabe

Yes, that's what I meant, but now that I see it written out, it's wrong because decltype keeps the const qualifier. You need the behavior of the non-standard typeof operator. BOOST_TYPEOF should work.
quantity

AMDG On 02/21/2013 01:56 PM, Ryan wrote:
Yes, that's what I meant, but now that I see it written out, it's wrong because decltype keeps the const qualifier. You need the behavior of the non-standard typeof operator. BOOST_TYPEOF should work.
quantity
(2.3 * nautical_mile); I tried this and it works. Is there a method, template or macro that lets me create the following two line like BOOST_UNITS_STATIC_CONSTANT?
typedef metric::nautical_mile_base_unit::unit_type nautical_mile_unit; static const nautical_mile_unit nautical_mile;
That way I don't have to create a name for the type and only use BOOST_TYPEOF if I need the type from the global constant.
There is no such macro (and it can't be done by any other means). If you want one, there's nothing stopping you from writing one yourself. Anything that I could write would need to be generic enough that it wouldn't save you anything. Also, I should point out that you don't need the intermediate typedef. BOOST_UNITS_STATIC_CONSTANT(nautical_mile, metric::nautical_mile_base_unit::unit_type); will work just fine. In Christ, Steven Watanabe

Also, I should point out that you don't need the intermediate typedef.
BOOST_UNITS_STATIC_CONSTANT(nautical_mile,
metric::nautical_mile_base_unit::unit_type); will work just fine.
This was what I was looking for. I found that BOOST_UNITS_STATIC_CONSTANT needs to be declared outside of the class. I think is due to the namespace the macro uses. I couldn't though use it to declare nautical_miles_per_hour. BOOST_UNITS_STATIC_CONSTANT(nautical_miles, metric::nautical_mile_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(hours, metric::hour_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(nautical_miles_per_hour, decltype(BOOST_TYPEOF(nautical_miles)() / BOOST_TYPEOF(hours)())); //This doesn't compile I could however do the following. static const decltype(BOOST_TYPEOF(nautical_miles)() / BOOST_TYPEOF(hours)()) nautical_miles_per_hour; I don't understand the difference. Ryan

AMDG On 02/22/2013 12:30 PM, Ryan wrote:
Also, I should point out that you don't need the intermediate typedef.
BOOST_UNITS_STATIC_CONSTANT(nautical_mile,
metric::nautical_mile_base_unit::unit_type); will work just fine.
This was what I was looking for. I found that BOOST_UNITS_STATIC_CONSTANT needs to be declared outside of the class. I think is due to the namespace the macro uses. I couldn't though use it to declare nautical_miles_per_hour.
BOOST_UNITS_STATIC_CONSTANT(nautical_miles, metric::nautical_mile_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(hours, metric::hour_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(nautical_miles_per_hour, decltype(BOOST_TYPEOF(nautical_miles)() / BOOST_TYPEOF(hours)())); //This doesn't compile
I could however do the following.
static const decltype(BOOST_TYPEOF(nautical_miles)() / BOOST_TYPEOF(hours)()) nautical_miles_per_hour;
I don't understand the difference.
Me neither. However, you don't need to use BOOST_TYPEOF. It would be simpler to write: decltype(nautical_miles / hours) In Christ, Steven Watanabe

Steven, I didn't notice I was getting a linking error for the following code that we discussed. It compiles fine but has an "unresolved external symbol" for the following. class A { static const metric::nautical_mile_base_unit::unit_type nautical_miles; static const metric::hour_base_unit::unit_type hours; static const decltype(nautical_miles / hours) nautical_miles_per_hour; }; If I move these lines outside the class everything compiles and links fine. What am I missing here? Ryan

AMDG On 02/25/2013 04:16 PM, Ryan wrote:
Steven,
I didn't notice I was getting a linking error for the following code that we discussed. It compiles fine but has an "unresolved external symbol" for the following.
class A { static const metric::nautical_mile_base_unit::unit_type nautical_miles; static const metric::hour_base_unit::unit_type hours; static const decltype(nautical_miles / hours) nautical_miles_per_hour; };
If I move these lines outside the class everything compiles and links fine. What am I missing here?
at namespace scope in A.cpp: const metric::nautical_mile_base_unit::unit_type A::nautical_miles; ... In Christ, Steven Watanabe

at namespace scope in A.cpp:
const metric::nautical_mile_base_unit::unit_type A::nautical_miles;
I don't have a .cpp. Everything is in the header. I tried doing the const thing after the class but it didn't work. Do I have to have a .cpp for it to work? Ryan //The following doesn't work. class A { static const metric::nautical_mile_base_unit::unit_type nautical_miles; static const metric::hour_base_unit::unit_type hours; static const decltype(nautical_miles / hours) nautical_miles_per_hour; } const metric::nautical_mile_base_unit::unit_type A::nautical_miles; const metric::hour_base_unit::unit_type A::hours; const decltype(nautical_miles / hours) A::nautical_miles_per_hour;

AMDG On 02/25/2013 04:33 PM, Ryan wrote:
at namespace scope in A.cpp:
const metric::nautical_mile_base_unit::unit_type A::nautical_miles;
I don't have a .cpp. Everything is in the header. I tried doing the const thing after the class but it didn't work. Do I have to have a .cpp for it to work?
Ryan
//The following doesn't work. class A { static const metric::nautical_mile_base_unit::unit_type nautical_miles; static const metric::hour_base_unit::unit_type hours; static const decltype(nautical_miles / hours) nautical_miles_per_hour; }
const metric::nautical_mile_base_unit::unit_type A::nautical_miles; const metric::hour_base_unit::unit_type A::hours; const decltype(nautical_miles / hours) A::nautical_miles_per_hour;
That will cause a different linker error. (multiple definitions instead of undefined symbol) It takes a bit of magic to define these in a header. BOOST_UNITS_STATIC_CONSTANT handles it, but it only works at namespace scope. The only to to define them inside the class and keep it header only, is to turn A into a template. In Christ, Steven Watanabe

That will cause a different linker error. (multiple definitions instead of undefined symbol)
It takes a bit of magic to define these in a header. BOOST_UNITS_STATIC_CONSTANT handles it, but it only works at namespace scope. The only to to define them inside the class and keep it header only, is to turn A into a template.
Okay. I'll just define them outside the class in the classes namespace. I'd rather keep the header only implementation than get the static defines in the class. Thanks again for the help. Ryan
participants (3)
-
Andrew Hundt
-
Ryan
-
Steven Watanabe