I would go with an assertion. Without any further information, I'd probably default to the non-static assert()non-static assert()
.
A comment would indeed be wishful thinking. Not only can it be ignored, but it can very easily go out of date if (when?) you decide 32 should no longer be the limit.
If this was a public API with other programmers using it, the exceptionexception would be beneficial as it tends to provide more debugging information, especially if you included a meaningful error message such as "walderFrey::palette size must be between 1 and 32 inclusive". Otherwise, they might have to dig into your source code and learn how your library works just to figure out why that random assert failed. But since this is just for your own use, there's not as much benefit in that. And you might as well get the (admittedly small) performance benefit of having the assert()assert()
disappear in non-debug builds.
I've also heard it argued that exceptionsexceptions should indicate unpredictable, exceptional conditions that may be unlikely to repeat or may not even be fixable, while assertions should indicate programmer errors that definitely can and should be fixed. I generally agree with this guideline when there is no public API to worry about.
The template solution is neat, but that raises a bigger question: should a size-1 palette and a size-32 palette be considered the same type? Does it make sense to assign one to the other? If it does not make sense, then that's an additional benefit of implementing this class as a template. But you should not decide whether to make this class a template solely because a static_assert()static_assert()
is slightly nicer than an assert()assert()
. A regular assert()assert()
is definitely "good enough". Normally, generic code involving templates is more complex, so I'd default to a "normal" class until I felt the complexity was justified, hence I'd recommend assert()assert()
unless you feel going with templates is justified for other reasons.