Инициализация структуры класса с вектором структур в списке инициализации конструктора - PullRequest
0 голосов
/ 18 мая 2019

Интересно, как я могу описать список инициализации конструктора, чтобы определить переменную класса типа struct, содержащего вектор структур:

class Class {

public:

Class() : _list( {{3, 4}} ) {}
Class(List _l) : _list(_l) {}

struct Value {
    int a;
    int b;
};

struct List {
    vector<Value> values;
};

private:
List _list;

}


int main() {
    Class c( {{2, 4}} );
}

Предположим, что какая-то обратная совместимость может привести к некоторым преимуществам такого подхода.

Поскольку код с конструктором по умолчанию только Class() : _list( {{3, 4}} ) {}, похоже, компилируется без ошибок, добавление конструктора Class(List _l : _list(_l) приводит к:

error: expected ')' before '_values'| и код с определением объекта возвращает:

error: no matching function for call to 'Class::Class(<brace-enclosed initializer list>, <brace-enclosed initializer list>)'|.

Я пробовал несколько способов решить эту проблему, например, несколько разных определений списка инициализации, разные способы передачи аргумента в конструкторе или определения конструкторов struct List. Часть из них, казалось, принесла упомянутые ошибки.

Наконец, мне интересно, можно ли достичь такой функциональности таким способом.

Спасибо за помощь и советы заранее.

1 Ответ

1 голос
/ 18 мая 2019

Просто добавьте еще одну пару скобок, и все будет в порядке!:

Class() : _list( {{{3, 4}}} ) {}

А также:

Class c( {{{2, 4}}} );

Конструкция с скобками обычно используется для обозначения скобок-инициализация элементов данных или построение элементов из диапазона.

Структуру Value здесь можно инициализировать просто с помощью {3,4}, поскольку она имеет 2 члена данных и никакого другого конструктора.
Однако в случае std::vector этот тип конструкции используется для указания набораэлементов, которые будут храниться в векторе при его построении.
Наконец, для List заключенный в фигурные скобки конструктор может использовать только один тип данных std::vector<Value>, чтобы использовать его для инициализации только данных.член values, который сам имеет тип std::vector<Value>.

Здесь каждому классу нужен инициализатор в скобках.Один для Value, один для std::vector<Value> и один для List.В случае Value в фигурных скобках может быть только 2 данных (самые внутренние фигурные скобки).Но для std::vector<Value> внутри фигурных скобок может быть одно или несколько данных типа Value.Наконец, для List в фигурных скобках может быть только один элемент данных (самые внешние фигурные скобки).
Например:

Class() : _list( {{{3, 4}, {5, 6}}} ) {}

также в порядке и приводит к тому, что в него помещаются 2 данных типа Valueвектор!

Кроме того, чтобы использовать структуры / классы-члены в конструкторах, сначала объявите их:

class Class {
public:
    struct Value;
    struct List;
    Class() : _list( {{{3, 4}}} ) {}
    Class(List _l) : _list(_l) {}
    struct Value {
        int a;
        int b;
    };
    struct List {
        std::vector<Value> values;
    };
private:
    List _list;
};

При сравнении было бы хорошо удалить фигурные скобкидля List Если класс был определен следующим образом:

class Class {
public:
    struct Value;
    struct List;
    Class() : _list( {3, 4} ) {}
    Class(List _l) : _list(_l) {}
    struct Value {
        int a;
        int b;
    };
    struct List {
        Value values;
    };
private:
    List _list;
};

Но это потому, что List (а также Value) не имеет определяемого пользователем конструктора , а List имеет только один член данных!

Удачи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...