MATLAB® Data API C++ поддерживает использование классов посетителя через функции matlab::data::apply_visitor_ref
и matlab::data::apply_visitor
. Эти функции принимают массив или ссылку на массив и visitor class как входные параметры.
apply_visitor
и функции apply_visitor_ref
отправляют операциям, заданным visitor class на основе типа входного массива. Visitor class задает операции, чтобы выполнить на определенных типах массива.
Используйте шаблон "посетитель" в случаях, таких как они:
Существует много операций, которые необходимо выполнить на массиве, и способ выполнить их зависит от типа массива.
Массив, возвращенный функцией, может иметь различные известные типы, и вы хотите обработать все случаи.
Вы работаете с гетерогенными структурами как массивы ячеек или массивы структур.
Функция apply_visitor
отправляет операции visitor class на основе типа входного массива. Синтаксис для вызова apply_visitor
принимает matlab::data::Array
и ваш экземпляр visitor class:
auto apply_visitor(matlab::data::Array a, V visitor)
Функция apply_visitor_ref
отправляет операции visitor class на основе типа ссылки на массив, переданной как вход. Синтаксис для вызова apply_visitor_ref
принимает matlab::data::ArrayRef
и ваш экземпляр visitor class:
auto apply_visitor_ref(const matlab::data::ArrayRef& a, V visitor)
Перегрузка оператора ()
Реализуйте своего visitor class, чтобы перегрузить оператор operator()
для типов массива, с которыми вы хотите работать. Например, предположите одну операцию, которую вы хотите реализовать, должен возвратить текст, содержавшийся в matlab::data::CharArray
как std::string
. Реализуйте операцию как это:
std::string operator()(matlab::data::CharArray arr){ return arr.toAscii(); }
Как другой пример, предположите, что вы хотите инвертировать логические значения в matlab::data::TypedArray
. В этом случае используйте ссылку на массив:
void operator()(TypedArrayRef<bool> boolArrRef) { std::cout << "Negate logical value: " << std::endl; for (auto &b : boolArrRef) { b = !b; } }
Необходимо использовать ссылку на элемент в основанном на области значений цикле for
, чтобы изменить значение в массиве.
Этот пример показывает, как использовать visitor class, чтобы задать операции, чтобы выполнить на определенных типах matlab::data::Array
.
Класс DisplayVisitor
реализует операции, чтобы отобразить содержимое массивов ячеек для массивов типов bool
, double
, и char
и содержавшие массивы ячеек. Можно добавить новые операции, чтобы поддержать другое содержимое массива ячеек путем добавления большего количества перегруженных функций.
type DisplayVisitor.cpp
#include "MatlabDataArray.hpp" #include <iostream> using namespace matlab::data; void DisplayCell(const CellArray cellArray); class DisplayVisitor { public: template <typename U> void operator()(U arr) {} void operator()(const TypedArray<bool> boolArr) { std::cout << "Cell contains logical array: " << std::endl; for (auto b : boolArr) { printf_s("%d ", b); } std::cout << "\n"; } void operator()(const TypedArray<double> doubleArr) { std::cout << "Cell contains double array: " << std::endl; for (auto elem : doubleArr) { std::cout << elem << " "; } std::cout << "\n"; } void operator()(const CharArray charArr) { std::cout << "Cell contains char array: " << std::endl; for (auto elem : charArr) { std::cout << char(elem); } std::cout << "\n"; } void operator()(const CellArray containedCellArray) { DisplayCell(containedCellArray); } }; void DisplayCell(const CellArray cellArray) { DisplayVisitor v; for (auto elem : cellArray) { apply_visitor(elem, v); } }
Чтобы использовать класс, передайте массив ячеек функции DisplayCell
.
type callDisplayCell.cpp
int main() { ArrayFactory factory; // Create cell array matlab::data::CellArray cellArray = factory.createCellArray({ 1,4 }, factory.createCharArray("A char array"), factory.createArray<bool>({ 1,2 }, { false, true }), factory.createArray<double>({ 2,2 }, { 1.2, 2.2, 3.2, 4.2 }), factory.createCellArray({ 1,1 }, false)); // Call function DisplayCell(cellArray); return 0; }
В этом примере класс CellModifyVisitor
реализует операции, чтобы изменить содержимое массивов ячеек типов bool
, double
, и char
и содержавшие массивы ячеек. Можно добавить новые операции, чтобы поддержать другое содержимое массива ячеек путем добавления большего количества перегруженных функций.
Вызовы функции ModifyCell
apply_visitor_ref
в цикле для каждого элемента в массиве ячеек. Поскольку цель состоит в том, чтобы изменить содержимое массива ячеек, этот пример использует ссылки на содержимое массива ячеек.
type CellModifyVisitor.cpp
#include "MatlabDataArray.hpp" #include "MatlabEngine.hpp" #include <iostream> using namespace matlab::data; void ModifyCell(CellArray &cellArray); class CellModifyVisitor { public: template <typename U> void operator()(U arr) {} void operator()(TypedArrayRef<bool> boolArrRef) { std::cout << "Negate logical value: " << std::endl; for (auto &b : boolArrRef) { b = !b; } } void operator()(TypedArrayRef<double> doubleArrRef) { std::cout << "Add 1 to each value: " << std::endl; for (auto &elem : doubleArrRef) { elem = elem + 1; } std::cout << "\n"; } void operator()(CharArrayRef charArrRef) { std::cout << "Modify char array" << std::endl; ArrayFactory factory; charArrRef = factory.createCharArray("Modified char array"); } void operator()(CellArrayRef containedCellArray) { CellModifyVisitor v; for (auto elem : containedCellArray) { apply_visitor_ref(elem, v); } } }; void ModifyCell(CellArray &cellArray) { CellModifyVisitor v; for (auto elem : cellArray) { apply_visitor_ref(elem, v); } }
Чтобы использовать класс, передайте массив ячеек функции ModifyCell
.
type callModifyCell.cpp
int main() { ArrayFactory factory; // Create cell array matlab::data::CellArray cellArray = factory.createCellArray({ 1,4 }, factory.createCharArray("A char array"), factory.createArray<bool>({ 1,2 }, { false, true }), factory.createArray<double>({ 2,2 }, { 1.2, 2.2, 3.2, 4.2 }), factory.createCellArray({ 1,1 }, false)); // Call function ModifyCell(cellArray); return 0; }
matlab::data::apply_visitor
| matlab::data::apply_visitor_ref