Я б робив
template<typename T>
T const pi = std::acos(-T(1));
або
template<typename T>
T const pi = std::arg(-std::log(T(2)));
Я б не вводив π до точної точності, яка вам потрібна . Що це навіть має означати? Точність вам потрібно це точність T, але ми нічого не знаємо про T.
Ви можете сказати: Про що ви говорите? Tбуде float, doubleабо long double. Отже, просто введіть точність long double, тобто
template<typename T>
T const pi = static_cast<T>(/* long double precision π */);
Але чи справді ви знаєте, що в майбутньому стандарт нового типу з плаваючою точкою не буде з ще більшою точністю, ніж long double? Ви цього не робите.
І тому перше рішення прекрасне. Ви можете бути повністю впевнені, що стандарт перевантажить тригонометричні функції для нового типу.
І, будь ласка, не кажіть, що оцінка тригонометричної функції при ініціалізації - покарання продуктивності.
3.14,3.141592іatan(1) * 4?