Заполнение коллекции QSharedPointer <T>в C ++ / Qt - PullRequest
1 голос
/ 25 апреля 2020

Я использую C ++ 17, G CC 7.4.0, Qt 5.12.x.

Я бы хотел заполнить QSharedPointer<T> коллекцию из QJsonArray (сериализованного Q_GADGETS) экземпляра используя универсальную функцию (шаблон). Так что, по крайней мере, QList и QVector могут быть заполнены этим (я не пытаюсь найти высокоскоростной подход). Предположим, что у нас есть T convert_func(const QJsonValue& value), который преобразует QJsonValue в T экземпляр.

for (const auto& json_value: qAsConst(json_array)){
auto ptr = QSharedPointer<T>::create(convert_func(json_value));
collection << ptr;
}

Итак, шаблон функции должен принимать типичные контейнеры Qt, которые содержат QSharedPointer (интеллектуальные указатели на Q_GADGETS). Как этого достичь?

Псевдокод:

QJsonArray json_array;
//...
//json_array has been filled
QVector<QSharedPointer<My_gadget>> gadget_vector = fill_gadgets<QVector<QSharedPointer<My_gadget>>>(json_array);
QList<QSharedPointer<My_gadget>> gadget_list = fill_gadgets<QList<QSharedPointer<My_gadget>>>(json_array);

//or like that (QSharedPointer is mandatory, that's why is implicit):
QVector<QSharedPointer<My_gadget>> gadget_vector = fill_gadgets<QVector,My_gadget>(json_array);
QList<QSharedPointer<My_gadget>> gadget_list = fill_gadgets<QList, My_gadget>(json_array);

Вы можете притвориться, что у нас есть std::array (или другая коллекция) вместо QJsonArray в качестве ввода. Проблема в описании выходной коллекции с использованием шаблона.

1 Ответ

1 голос
/ 29 апреля 2020

Если вы хотите преобразовать из любого исходного контейнера (ContSource) в другое место назначения контейнера с некоторым Smart-указателем в середине, следующий фрагмент кода должен выполнить задание.

Он использует параметр шаблона шаблона для обоих ContDest и ContSource. Аргумент шаблона variadi c для обоих из них не требуется, если вы используете только контейнер Qt, поскольку они задаются только одним аргументом, но если вы используете контейнеры std, они определяются типом и распределителем. Таким образом, код с аргументом шаблона variadi c отлично работает с обоими, как показано в примере.

template < template <typename... Args> class ContDest,
template <typename... Args> class ContSource,
template<typename... Args> class SmartPointer,
typename E>
ContDest<SmartPointer<E>> fillGadget(const ContSource<E>& values)
{
    ContDest<SmartPointer<E>> res;
    for (const auto & val : values)
        res.push_back(SmartPointer<E>(new E(val)));

    return res;

}

const QList<int> vals = { 1,2,3 };
auto gadget_stdvector = fillGadget< std::vector, QList, std::shared_ptr, int >(vals);

std::deque<int> val2 = { 1 ,2, 3 };
auto gadget_qvector = fillGadget< QVector, std::deque, QSharedPointer, int >(val2);

Обратите внимание, что он неоптимален для всех случаев, когда значения исходного контейнера и контейнера назначения сохраняются непрерывно ,

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