[#mp_units-derived_unit]
= xref:mp_units.adoc[mp&lowbar;units]::derived&lowbar;unit
:relfileprefix: ../
:mrdocs:

Measurement unit for a derived quantity

== Synopsis

Declared in `&lt;mp&hyphen;units&sol;framework&sol;unit&period;h&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;&sol;&ast; implementation-defined &ast;&sol;&period;&period;&period; Expr&gt;
struct derived&lowbar;unit final
    : &sol;&ast; implementation-defined &ast;&sol;
----

== Description

Derived units are defined as products of powers of the base units&period;

Instead of using a raw list of exponents this library decided to use expression template syntax to make types more digestable for the user&period; The positive exponents are ordered first and all negative exponents are put as a list into the `per&lt;&period;&period;&period;&gt;` class template&period; If a power of exponent is different than `1` the unit type is enclosed in `power&lt;Dim, Num, Den&gt;` class template&period; Otherwise, it is just put directly in the list without any wrapper&period; There is also one special case&period; In case all of the exponents are negative then the `one` being a coherent unit of a dimensionless quantity is put in the front to increase the readability&period;

For example&colon;

[,cpp]
----
{.cpp}
 static_assert(is_of_type<inverse(second), derived_unit<one, per<second>>>);
 static_assert(is_of_type<one / inverse(second), second>);
 static_assert(is_of_type<one * second, second>);
 static_assert(is_of_type<metre * metre, derived_unit<power<metre, 2>>>);
 static_assert(is_of_type<metre * second, derived_unit<metre, second>>);
 static_assert(is_of_type<metre / second, derived_unit<metre, per<second>>>);
 static_assert(is_of_type<metre / square(second), derived_unit<metre, per<power<second, 2>>>>);
 static_assert(is_of_type<watt / joule, derived_unit<watt, per<joule>>>);
----
Every unit in the library has its internal canonical representation being the list of exponents of named base units (with the exception of `kilogram` which is represented as `gram` here) and a scaling ratio represented with a magnitude&period;

Two units are deemed convertible if their canonical version has units of the same type&period; Two units are equivalent when they are convertible and their canonical versions have the same scaling ratios&period;

The above means that&colon;

* `1&sol;s` and `Hz` are both convertible and equal
* `m` and `km` are convertible but not equal
* `m` and `m²` ane not convertible and not equal

[NOTE]
====
This also means that units like `hertz` and `becquerel` are also considered convertible and equal&period;

====

[NOTE]
====
User should not instantiate this type! It is not exported from the C&plus;&plus; module&period; The library will instantiate this type automatically based on the unit arithmetic equation provided by the user&period;

====

== Base Classes

[cols="1,4"]
|===
|Name|Description

| `&sol;&ast; implementation-defined &ast;&sol;`
| 
|===

== Template Parameters

[cols="1,4"]
|===
|Name|Description

| *Us*
| a parameter pack consisting tokens allowed in the unit specification (units, `power&lt;U, Num, Den&gt;`, `per&lt;&period;&period;&period;&gt;`)
|===


[.small]#Created with https://www.mrdocs.com[MrDocs]#
