It's not apples to oranges, but using #define is simply the older, "C" way of doing things.
using constint UNSET { 0 };
or constexprint UNSET { 0 };
is definitely the modern, "C++" way of doing it. It's type safe, and will be optimized away just as easily as the old #define way.
Side note: Some people will argue that ALL_CAPS variable should be reserved for #defined macros only. I personally tend to follow this, but there's no set rules that everyone agrees on, so do what works best for you.
Side note: Some people will argue that ALL_CAPS variable should be reserved for #defined macros only.
While this is true with C, especially since a constant in C is a #defined macro, in C++ many people use all caps for global constants as well as macros (although in C++ macros are frowned upon in most cases).
and I disagree, because about 3/4 of the constants I use are specifically lower case in 'the world'. EG e = 2.71828 ... it is never E.
#define is not just old, it can cause problems from time to time. Best to not use macros at all without a very good reason to do so in modern c++. There are one or two uses for them in things like debugging that I am unaware of a replacement for; I think there are some extensions etc that you can print what routine you are currently in for example to create a generic 'where did it really crash' print statement macro.
For that specific point, I would suggest a name involving "Euler's Number". I don't usually have to deal with e though, since I feel like a lot of math doesn't force you to use it directly (as in, for non-exponent operations, of course there are exceptions), or you use std::exp.
One of the annoyances with the Wolfram language is just that -- reserved single-letter names.
the trouble with using a nice big fat name is it screws up the math.
instead of x = y/e you get x = y/EULERS_NUMBER which isnt so bad in a 2 term equation but when you get a hairy long equation, it explodes into a mess that does not remotely resemble the original recognizable textbook form in a hurry.
Honestly I haven't used e much either, just a few places. It was easier to use as an example than aerospace jargon letters like a (which is a variable but still, you use 1 letter so it matches the textbook form equations).
We did try naming and spelling them out for a period. It was just unmanageable.
I agree with jonnin: Use a meaningful name, unless one wants to match the variables shown in the technical documentation's mathematical equation.
Obviously it pays to document where the equations come from, and spell out confusing things. For example: in Geodesy e means eccentricity, not Eulers constant.
One solution could be to put the constants into a namespace.
1 2 3 4 5
namespace math_constants
{
constdouble pi = 3.14;
constdouble e = 2.72;
};
If you only use a constant once or twice and is worried that the short names might clash with other variables you can just use the full name.
1 2 3 4
void print_fact()
{
std::cout << "The value of π is approximately " << math_constants::pi << ".\n";
}
If you happen to use the constants a lot within a file or within a function you can use using namespace inside that file or function which will allow you to use the constants without having to use the namespace name.
I am talking about global constants, not local variables or local constants. IMO, constant global variables should have meaningful names, except in very rare circumstances, even if you have to break those large calculations into sub-calculations in order to keep your sanity.
Now if you're writing code for a specific "locale" where otherwise meaningless names have meaning then by all means use those names. However you would still be advised to document what those names actually mean.
However in most situations you would be advised against using single letter names except in very local scopes.
Even using acronyms should usually be avoided when writing code for general consumption since there may be multiple meanings for any one acronyms depending on content.
As an aside, I just discovered clang++ can deal with Unicode identifiers directly, so now I can have Greek characters for variable names. I suppose now it is an issue if the code can only be compiled with clang++. OTOH with g++ it seems isn't standard compliant on this particular point.
g++ can do it too, but involves running a shell script to convert the Unicode. I find it untenable to have multiple files: MyClass.hpp and MyClassUTF.hpp and 2 cpp files as well.
THAT has been a long time coming. Symbolic code, once fully supported, will be a boon to a lot of coders out there, while adding creative new ways to make code even harder to read in the hands of the gremlins.
The thing is, at least now you know that this thing in general exists, which is a whole lot better than not knowing. So some time in the future you could say: "I know about the basic idea of constexpr, but there can also be constexpr functions and constructors, so I will read up about them now"
I find this idea useful for any system whether it be software or anything else. It is good to have an overview knowledge of all the things the system can do, as opposed to a detailed knowledge of say 5% and no knowledge of the rest. The latter is where the majority of computer users reside.
I see it all the time, like a typist not knowing and not interested in learning about paragraph numbering, but then complains about how much work there is to do when the Engineer completely reorders chapters and paragraphs in an entire document.