Adrian
Adrian

Reputation: 9600

Create inline multidimensional arrays in C++

I have the following program, which I'd like to change to declare the multidimensional array inline:

int main() {
  int x[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

  for (const auto& [y, z] : x) {
    std::cout << y << ", " << z << std::endl;
  }
}

Is there a way to create inline arrays? Something like this:

  for (const auto& [y, z] : <magic>{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}) {
    std::cout << y << ", " << z << std::endl;
  }

Upvotes: 1

Views: 179

Answers (2)

RedFog
RedFog

Reputation: 1015

you can try a wrapper of C-style array to make it:

template<typename T>
struct xarray{
    T data;

    auto begin(){
        using std::begin;
        return begin(data);
    }
    auto end(){
        using std::end;
        return end(data);
    }
};
template<typename T, typename... Y>
xarray(T, Y...) -> xarray<T[sizeof...(Y) + 1]>;
template<typename T, size_t X>
xarray(T (&&)[X]) -> xarray<T[X]>;
template<typename T, size_t X, size_t Y>
xarray(T (&&)[X][Y]) -> xarray<T[X][Y]>;
// ...

int main(){
    for (auto&& [x, y] : xarray{{ {0, 1}, {0, 2} }}){ // additional {} is needed.
        std::cout << x << " " << y << std::endl;
    }
}

it's exactly equal to your code by C-style array.

Upvotes: 0

mattlangford
mattlangford

Reputation: 1260

Not a very nice way, here is a possibility though:

for (const auto& [y, z] : std::array<std::pair<int, int>, 4>{{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}}) {
    std::cout << y << ", " << z << std::endl;
}

One dimensional arrays like can be done using template type deduction with more modern versions of c++, which is a bit cleaner:

for (const auto& x : std::array{0, 1, 2}) {
    std::cout << x << std::endl;
}

Introducing pairs makes it a fair bit messier though since the deduction doesn't work as nicely as you'd hope.

Upvotes: 2

Related Questions