Reputation: 3
Abstractly, say you were building a physics simulation and needed many universal constants or typical values for things like mass. It feels like there should be a standard approach to implementing this? I'm mainly a hobbiest, using C++, and I can think of ways it can be done but unsure what should be done, and I'm worried I'd hit some messy pitfall.
So if you had constants like g, G, pi, alpha, e, h, h-bar etc and lots of values like "Typical Star: Mass = 1 MSolar, wavelength = 600nm" and so on. how would you implement them and potentially group and organise them in a way thats efficient?
I was considering just a header file with the values as either #define macros, or consts, maybe even a std::map, but that feels like adding a lot of global variables in a way that would quickly get out of hand. Is it just something to endure or are there cleaner ways?
Upvotes: 0
Views: 331
Reputation: 9545
In C++20 many mathematical numeric constants can be included via #include <numbers>
. Beyond that in C++, don't use #define
, prefer either
constexpr double pi = 3.14159265358979323846;
or
const double pi = 3.14159265358979323846;
The main advantage of using constexpr
over const
is that constexpr
guarantees that the value of the constant is computed at compile time, whereas const only guarantees that the value is not modified at runtime. This means that constexpr constants can be used in contexts where a compile-time constant expression is required, such as in array sizes or template arguments, although typically this kind of usage is more applicable to integer constants.
Upvotes: 0
Reputation: 29985
The C++ way of doing this is to have them as inline constexpr
variables in a header file. That's what the standard does with some constants. You can define yours:
namespace Constants {
inline constexpr auto goldenRatio = 1.61803398875;
// ...
};
Upvotes: 1
Reputation: 76829
Some of these already exist in the standard library and it may be a good idea to follow the approach that the standard library uses to implement more of them.
See https://en.cppreference.com/w/cpp/numeric/constants, for example an implementation for Euler's number looks (slightly simplified) like this in C++20 (in the namespace std::numbers
for the standard library, but you should of course use your own):
// variable template for floating point types
template<std::floating_point T> constexpr T e_v = /* value of constant as a literal as precise as possible/neccessary */;
// short-hand for the double case
inline constexpr double e = e_v<double>;
And then one can use std::numbers::e
for Euler's number as a double
or std::numbers::e_v<float>
for Euler's number as a float
, and so on.
Upvotes: 0