我用的是C++17,GCC 7.4.0,Qt 5.12.x。
我想使用通用函数(模板)从QJsonArray
(序列化的Q_GADGETS
)实例填充QSharedPointer<T>
集合。因此,至少,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;
}
因此,函数模板必须接受包含QSharedPointer (指向Q_GADGETS的智能指针)的典型Qt容器。如何才能做到这一点?
伪码:
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
作为输入。问题出在使用模板描述输出集合时。
发布于 2020-04-29 16:27:46
如果你想从任何源容器(ContSource)转换到其他容器目标,中间有一些智能指针,下面的代码片段应该可以完成这项工作。
它对ContDest和ContSource都使用模板参数。如果你只使用Qt容器,那么它们的可变模板参数都是不需要的,因为它们只由一个参数模板化,但如果你使用std容器,就会有类型和分配器的模板化。因此,如示例所示,带有可变模板参数的代码可以很好地处理这两种情况。
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);
请注意,对于源容器和目标容器的值被连续存储的所有情况,它都是次优的。
https://stackoverflow.com/questions/61429750
复制相似问题