Передать 1d или 2d вектор конструктору того же класса - PullRequest
0 голосов
/ 25 июня 2019

Я собираюсь создать класс, обрабатывающий 2-й вектор двойников. Я хочу передать либо вектор векторов, либо простой вектор двойников (в случае, если второе измерение имеет ширину 1 элемент) в конструктор. Кроме того, это для модального диалога для редактирования базовых данных, поэтому я передаю вектор по ссылке.

Код для справки о том, чего я пытаюсь достичь:

class TableEditDialog {
    using Table2d = std::vector<std::vector<double>>;

public:
    TableEditDialog(Table2d & data) : m_data( data ) {}
    TableEditDialog(std::vector<double> & data); // ?

private:
    Table2d& m_data;
};

В случае передачи простого вектора пар с N элементами мне нужно, чтобы m_data было либо vector<vector<double>>, которое содержит N векторов одного элемента, либо один вектор из N элементов.

Я пытался использовать делегирующие конструкторы безуспешно. Также я пытался создать новый временный 2d вектор во втором конструкторе, но это нарушает идею передачи по ссылке для редактирования базовых данных.

Ответы [ 2 ]

2 голосов
/ 25 июня 2019

Сделать TableEditDialog шаблоном класса, чтобы тип мог быть указан при построении.

template<class T>
class TableEditDialog {
public:
  TableEditDialog(T& data) : m_data( data ) {}
private:
  T& m_data;
};

Вы также можете сделать функцию, которая поможет с выводом типа:

template<class T>
TableEditDialog<T> make_table_edit_dialog(T& data) {
  return data;
}

Тогда вы можете сделать:

std::vector<double> d1d;
std::vector<std::vector<double>> d2d;

auto ted1 = make_table_edit_dialog(d1d);
auto ted2 = make_table_edit_dialog(d2d);

РЕДАКТИРОВАТЬ:

Если вы хотите преобразовать регистр 1D-массива в 2D-массив, вы можете перегрузить конструктор для 1D-вектора и инициализировать m_data, скопировав в него вектор:

class TableEditDialog {
  using Array1d = std::vector<double>;
  using Array2d = std::vector<Array1d>;
public:
  TableEditDialog(Array2d& data) : m_data( data ) {}
  TableEditDialog(Array1d& data) : m_data(1, data) {}
private:
  Array2d m_data;
};
1 голос
/ 25 июня 2019

Вы можете конвертировать 1d вектор в 2d вектор, хранящий ссылки элемента.Единственным недостатком такого решения является то, что вам не разрешено играть с этим 1d-вектором, пока вы не закончите редактирование, в других местах все может сломаться.

Вот пример:

TableEditDialog(std::vector<double> & data) {
    std::vector<std::vector<std::reference_wrapper<double>>> result(data.size());
    std::transform(data.begin(), data.end(), result.begin(), [](double& d) {return {{d}};});
}

Хотя,Я не проверял это, и, возможно, вам нужно использовать {{std::forward(d)}} в лямбда-выражении.

Единственная проблема заключается в том, что у вас другое определение m_data, но та же семантика доступа, поэтому вам нужно либо использовать шаблонный кодчтобы получить к нему доступ или использовать std :: option.

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