In C++, to have a tidier code, I want to declare a set of values as constants in my header file, example :
constexpr float SIZE_SMALL = 1.5f;
constexpr float SIZE_MEDIUM = 2.5f;
constexpr std::string COLOR_RED = "RED";
constexpr std::string MATERIAL_SILK = "SILK";
...etc
But this is getting too long and clumsy. Also, some constants can be grouped together because they describe different values of the same property e.g. SIZE_SMALL
and SIZE_MEDIUM
.
What is the best way to write this in my header file? I thought about structs e.g.
struct SIZE
{
float SMALL;
float MEDIUM;
}
but then I have to declare and define a variable in my .cpp and that kinda beats the purpose of all this.
then I have to declare and define a variable in my .cpp and that kinda beats the purpose of all this.
No you dont. You can make the fields static
and constexpr
:
struct SIZES {
static constexpr const float SMALL = 1.5f;
};
However, I recommend to not do this. Not only you do not have to create an instance of this class, but also you should not create an instance of this class (what for?). So why use a class in the first place? Use namespace
s instead to group constants:
namespace SIZES {
constexpr float SMALL = 1.5f;
}
I have some 50+ of these constants in the same name space
Unless you find a way to make the compiler read your mind, you have to write them all down somewhere. Serisously, the only way this could be condesned is if there is some relation between those constants, as eg SMALL + 1.0f = MEDIUM
, but thats not apparent from your question.
This depends on your actual usage but consider using proper strong types instead of basic types. For instance, to declare sizes, make them of type size
, not float
. This doesn’t directly solve your grouping problem but it gives you all of the other benefits of strong typing, and may also help with grouping:
struct size {
private: float value;
public:
explicit constexpr size(float value) : value{value} {}
explicit constexpr operator float() const noexcept { return value; }
};
namespace default_sizes {
constexpr auto SMALL = size{1.5f};
constexpr auto MEDIUM = size{2.5f};
// …
}
In fact, for domain-specific usage, except in very limited cases, I’d generally avoid bare basic types and always encapsulate them in their own domain-specific type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With