状況
例
-
円周 = π × 半径 × 2
と算数で習う。 - 地球の半径は
6.378'137e+6
m と WGS84 に書いてある。 - 地球の赤道の長さは?
#include <boost/units/systems/si.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/units/io.hpp>
#include <iostream>
namespace some_app
{
using namespace boost::units;
using namespace boost::units::si;
using float_type = long double;
using length_type = quantity< length, float_type >;
/// @brief π
constexpr auto pi = boost::math::constants::pi< float_type >();
/// @brief 地球の半径(ref. WGS84)
const length_type earth_equatorial_radius = 6.378'137e+6 * meters;
/// @brief 地球の赤道の長さ
const length_type earth_equator_length = pi * earth_equatorial_radius * 2; // <-- Oops! Compile Error!!
}
int main()
{
std::cout << some_app::earth_equator_length;
}
Oops! Compile Error!!
prog.cc:29:76: error: no match for 'operator*' (operand types are 'boost::units::multiply_typeof_helper<long double, boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > > >, long double> >::type {aka boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > > >, long double>}' and 'int')
const length_type earth_equator_length = pi * earth_equatorial_radius * 2; // <-- Oops! Compile Error!!
^
方法
仕込み
/// @brief 無次元数 × 単位付き型
template<typename UNIT, typename IN_BASE, typename IN_FACTOR >
inline auto operator*( const IN_FACTOR& in_factor, const quantity< UNIT, IN_BASE >& in_base )
{ return static_cast< IN_BASE >( in_factor ) * in_base; }
/// @brief 単位付き型 × 無次元数
template<typename UNIT, typename IN_FACTOR, typename IN_BASE >
inline auto operator*( const quantity< UNIT, IN_BASE >& in_base, const IN_FACTOR& in_factor )
{ return in_base * static_cast< IN_BASE >( in_factor ); }
期待動作するソース全体
#include <boost/units/systems/si.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/units/io.hpp>
#include <iostream>
namespace some_app
{
using namespace boost::units;
using namespace boost::units::si;
using float_type = long double;
using length_type = quantity< length, float_type >;
/// @brief 無次元数 × 単位付き型
template<typename UNIT, typename IN_BASE, typename IN_FACTOR >
inline auto operator*( const IN_FACTOR& in_factor, const quantity< UNIT, IN_BASE >& in_base )
{ return static_cast< IN_BASE >( in_factor ) * in_base; }
/// @brief 単位付き型 × 無次元数
template<typename UNIT, typename IN_FACTOR, typename IN_BASE >
inline auto operator*( const quantity< UNIT, IN_BASE >& in_base, const IN_FACTOR& in_factor )
{ return in_base * static_cast< IN_BASE >( in_factor ); }
/// @brief π
constexpr auto pi = boost::math::constants::pi< float_type >();
/// @brief 地球の半径(ref. WGS84)
const length_type earth_equatorial_radius = 6.378'137e+6 * meters;
/// @brief 地球の赤道の長さ
const length_type earth_equator_length = pi * earth_equatorial_radius * 2; // <-- Oops! Compile Error!!
}
int main()
{
std::cout << some_app::earth_equator_length;
}
出力例
4.0075e+07 m