Невозможно добавить константный (структурный) тип в массив - PullRequest
6 голосов
/ 16 февраля 2011

В одной структуре Shape I есть функция:

...
import graphics.line;

struct Shape {
    Line[] lines;

    void addLine(Line l) {
        lines ~= l;
    }
}

Строка также является структурой, но когда я добавляю "in Line l" в качестве объявления аргумента для addLine(), компилятор выдает ошибкуwith:

shape.d (12): Ошибка: невозможно добавить тип const (Line) к типу Line []

Странно то, что у меня есть похожий кусоккода в другом модуле, и он работает ... Итак, мой вопрос, почему компилятор не устраивает его в этом случае?

1 Ответ

12 голосов
/ 16 февраля 2011

В принципе, работает ли это, зависит от того, какие члены есть в вашей структуре.Класс хранения in эквивалентен const scope.Таким образом, запись void addLine(in Line l) означает, что l является постоянным.И поскольку const является транзитивным, все Line l члены структуры также const.

Однако Shape член Line[] lines не является const.Итак, вы пытаетесь добавить const Line l к чему-то, что не const.Возможно ли это, зависит от типов всех членов struct Line l.Если все члены line имеют семантику значения (копирования), это добавление (которое является назначением) возможно.Если какой-либо из членов имеет (некоторую) ссылочную семантику (например, копируется указатель), это добавление больше невозможно.В противном случае вы могли бы дать const Line lc в addLines, но получили бы неконстантный член lines.Благодаря этому вы можете изменить значение с помощью эталонной семантики, косвенно изменив значение оригинала lc, тем самым нарушив гарантию const, а именно транзитивность const в D.

Пример:

class C { }

struct Line {
    int i;
    // int* p;               // if you uncomment this, addLine fails
    // C c;                  // if you uncomment this, addLine fails
}

struct Shape { 
    Line[] lines;
    void addLine(in Line l) { lines ~= l; }
}

void main() { }

Редактировать: Кстати, еще один способ заставить его работать - изменить Line[] lines; на const(Line)[] lines;.Если массив содержит только const элементов, и возможно добавление const l в addLine.

...