C++2a(C++20)標準ライブラリ<numbers>では、変数テンプレート(variable template)*1により浮動小数点型(float
, double
, long double
)にあわせた数学定数を提供する。一方、浮動小数点型以外によるプライマリテンプレート利用はill-formedとなることが要請されている。
#include <numbers> // float型精度の円周率π float pi_f = std::numbers::pi_v<float>; // OK // int型の円周率π? int pi_i = std::numbers::pi_v<int>; // NG: ill-formed
N4861 (C++2a DIS) 26.9.2/p3より引用。
A program that instantiates a primary template of a mathematical constant variable template is ill-formed.
GCC/libstdc++
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/numbers
template<typename _Tp> using _Enable_if_floating = enable_if_t<is_floating_point_v<_Tp>, _Tp>; template<typename _Tp> inline constexpr _Tp pi_v = _Enable_if_floating<_Tp>(3.14159...);
Clang/libcxx
https://github.com/llvm/llvm-project/blob/master/libcxx/include/numbers
template <class T> inline constexpr bool __false = false; template <class T> struct __illformed { static_assert(__false<T>, "..."); }; template <class T> inline constexpr T pi_v = __illformed<T>{}; template <class T> concept __floating_point = std::is_floating_point_v<T>; template <__floating_point T> inline constexpr T pi_v<T> = 3.14159...;
MSVC
https://github.com/microsoft/STL/blob/master/stl/inc/numbers
// stl/inc/xstddef template <class> inline constexpr bool _Always_false = false; template <class _Ty> struct _Invalid { static_assert(_Always_false<_Ty>, "..."); }; template <class _Ty> inline constexpr _Ty pi_v = _Invalid<_Ty>{}; template <floating_point _Floating> inline constexpr _Floating pi_v<_Floating> = static_cast<_Floating>(3.14159...);
関連URL
- P2041R0 Deleting variable templates
- cppreference: <numbers>, Variable template
- cpprefjp: <numbers>, 変数テンプレート