How would one best implement a single function that accepts two std::array<int, [size]>
arguments, each with a size constrained by a corresponding set of values known at compile-time?
- The function must only accept arrays with sizes derived from a given set (enum/macro/etc)
- The sets of allowable array "sizes" may be changed in the future and may be large (effectively precluding function overloading)
- The function itself should remain fixed regardless of changes to the sets of allowable array "sizes"
The question "Passing a std::array of unknown size to a function", while similar, doesn't appear to directly apply.
The following works in C++14 but seems unnecessarily redundant & messy:
#include <type_traits>
#include <array>
// Add legal/allowable sizes for std::array<> "types" here
// Note: Not married to this; perhaps preprocessor instead?
enum class SizesForArrayX : size_t { Three = 3, Four, Forty = 40 };
enum class SizesForArrayY : size_t { Two = 2, Three, EleventyTwelve = 122 };
// Messy, compile-time, value getter for the above enum classes
template <typename S>
constexpr size_t GetSizeValue(const S size)
{ return static_cast<std::underlying_type_t<S>>(size); }
// An example of the function in question; is Template Argument Deduction
// possible here?
// Note: only arrays of "legal"/"allowable" sizes should be passable
template <SizesForArrayX SX, SizesForArrayY SY>
void PickyArrayHandler(
const std::array<int, GetSizeValue(SX)>& x,
const std::array<int, GetSizeValue(SY)>& y)
{
// Do whatever
for (auto& i : x) i = 42;
for (auto& i : y) while (i --> -41) i = i;
}
Calling the above:
int main()
{
// Declare & (value-)initialize some arrays
std::array<int, GetSizeValue(SizesForArrayX::Forty)> x{};
std::array<int, GetSizeValue(SizesForArrayY::Two>) y{};
//PickyArrayHandler(x, y); // <- Doesn't work; C2672, C2783
// This works & handles arrays of any "allowable" size but the required
// template params are repetitions of the array declarations; ick
PickyArrayHandler<SizesForArrayX::Forty, SizesForArrayY::Two>(x, y);
}
...which is ugly, inelegant, slow-to-compile, and requires the declared array size match the explicit "size" passed to the PickyArrayHandler
function template.
For the specific example above: Is there a way for the
PickyArrayHandler
template to deduce the sizes of the passed arrays?Generally speaking: Is there a different, better approach?