D - Установить значение по умолчанию для члена структуры, который является многомерным статическим массивом

Я использую язык программирования D. Я хочу иметь struct содержащий многомерный статический массив ints изначально заполнен ненулевым значением (в моем случае ноль является допустимой записью, и я хочу изначально пометить все записи как недействительные). Как это struct, он не может иметь конструктор по умолчанию. Вместо этого я могу предоставить значение по умолчанию для члена struct,

Вопрос в том, как записать это значение многомерного массива в краткой и удобочитаемой форме. Есть ли какая-либо удобная функция, особый синтаксис или идиома для этого?


Вот что я придумал.

import std.range;
import std.stdio;

struct S
{
    static immutable int SIZE =  3;
    static immutable int NA   = -1;

    int [SIZE] [SIZE] a = NA.repeat(SIZE).array().repeat(SIZE).array();
}

void main()
{
    S s;
    writeln(s);
}

Это печатает массив -1как и ожидалось:

S([[-1, -1, -1], [-1, -1, -1], [-1, -1, -1]])

Тем не менее, выражение NA.repeat(SIZE).array().repeat(SIZE).array() выглядит длинным, и я подозреваю, что мог бы быть лучший (более идиоматичный, более читаемый) способ выразить свое намерение.


Обновите еще несколько попыток:

  1. int [SIZE] [SIZE] a = NA; не компилируется, даже с текущей бета-версией: dmd-2.066-b2.

  2. int [SIZE] [SIZE] a = NA.repeat (SIZE).array (); компилирует и делает вещь. Тем не менее, последовательность страдает.

  3. int [SIZE] [SIZE] a = [NA, NA, NA]; Похоже, это по существу вышеприведенное выражение, упрощенное. Компилируется, но заполняет только первый трехэлементный подмассив NAs. Два других подмассива содержат что-то вроде мусора. Это особенность частичной инициализации? Для меня это больше похоже на ошибку, например, компилятор принимает неверный код.

  4. int [SIZE] [SIZE] a = [NA]; устанавливает первый подмассив в [-1, 0, 0] а остальное на ту же фигню, что и предыдущая попытка.

  5. Существует также fill в std.algorithm, но он работает для диапазонов (не диапазонов диапазонов) и не выглядит так, как будто его легко использовать в инициализаторе. По крайней мере, это не будет короче.

1 ответ

Решение

Как насчет чего-то вроде этого:

module main;
import std.stdio: writeln;

enum SIZE =  3;
enum NA = -1;

struct Int {
    int v = -1;
    alias v this;
}

struct S
{
    Int [SIZE] [SIZE] a;
}

void main()
{
    S s;
    writeln(s);
}
Другие вопросы по тегам