从 QVariant 接收未知的模板化对象
receiving unknown templated object from QVariant
我有一个可变参数模板 class 用于保存来自自己网络的答案 class
enum class TaskType {readReg, writeReg, readRnd, writeRnd, readBlock, writeBlock, pause};
template<typename... Args> class Reply {
public:
Reply(TaskType t, Args...params): t(t), tuple(std::make_tuple(params...)) {}
Reply();
TaskType t;
auto getData() const {return std::get<4>(tuple);} //simplified getter of safe function that deals with oversizing
private:
std::tuple<Args ...> tuple;
};
我注册模板签名以将它们保存在 Qvariant 中
using ReadRegReply = Reply<TaskType, uint, uint, uint, uint, uint> ;
using WriteReply = Reply<TaskType, uint, uint, uint> ;
using ReadRndReply = Reply<TaskType, uint, uint, uint, QVector<uint>, QVector<uint>> ;
using ReadBlockReply = Reply<TaskType, uint, uint, uint, uint, QVector<uint>> ;
Q_DECLARE_METATYPE(QVector<uint>)
Q_DECLARE_METATYPE(ReadRegReply)
Q_DECLARE_METATYPE(WriteReply)
Q_DECLARE_METATYPE(ReadRndReply)
Q_DECLARE_METATYPE(ReadBlockReply)
然后我这样处理它:
class Task: public QObject{
public:
//c-tor and some functions, virtual functions etc
template <class TReply> bool applyReply(TReply reply){
varReply = QVariant::fromValue(reply);
}
auto getData(){ //here I should return data from tuple inside reply.
QVariant::Type t = varReply.type();
auto l = varReply.value<t>();// t is not a constexp // t is not a reply type but enum QVariant::type, as I understand.
return l.getData(); // l has no method getData
}
QVariant varReply; //this is the qvariant that contains templated reply;
}
我想念 QVariant 中的一些东西。我认为注册类型应该以某种方式存储在 Qvariant 中,但事实并非如此。其他问题:我不能使用c++17;它将用于许多具有不同回复签名的项目。有没有办法保留这些类型并在将来添加它们而无需完全重构?我考虑过某种经理class,但我可能想多了
QVariant
仅包含 Qt 中使用的内置类型的有用类型信息。如果有其他类型,需要在别处记录
class Task: public QObject{
public:
template <class TReply> bool applyReply(TReply reply){
varReply = QVariant::fromValue(reply);
}
template <class TReply> TReply getData(){reply.
return varReply.value<TReply>();
}
QVariant varReply;
}
void usesWriteTask() {
Task task;
task.applyReply(WriteReply());
// ...
WriteReply back = tast.getData<WriteReply>();
}
或者,如果您可以使用 boost,则可以使用 boost::variant
,这激发了 std::variant
class Task: public QObject{
public:
using VarReply = boost::variant<ReadRegReply, WriteReply, ReadRndReply, ReadBlockReply>;
bool applyReply(VarReply reply) {
varReply = reply;
}
template <class Result> Result getData(boost::static_visitor<Result> & visitor) {
return varReply.apply_visitor(visitor);
}
VarReply varReply;
}
我有一个可变参数模板 class 用于保存来自自己网络的答案 class
enum class TaskType {readReg, writeReg, readRnd, writeRnd, readBlock, writeBlock, pause};
template<typename... Args> class Reply {
public:
Reply(TaskType t, Args...params): t(t), tuple(std::make_tuple(params...)) {}
Reply();
TaskType t;
auto getData() const {return std::get<4>(tuple);} //simplified getter of safe function that deals with oversizing
private:
std::tuple<Args ...> tuple;
};
我注册模板签名以将它们保存在 Qvariant 中
using ReadRegReply = Reply<TaskType, uint, uint, uint, uint, uint> ;
using WriteReply = Reply<TaskType, uint, uint, uint> ;
using ReadRndReply = Reply<TaskType, uint, uint, uint, QVector<uint>, QVector<uint>> ;
using ReadBlockReply = Reply<TaskType, uint, uint, uint, uint, QVector<uint>> ;
Q_DECLARE_METATYPE(QVector<uint>)
Q_DECLARE_METATYPE(ReadRegReply)
Q_DECLARE_METATYPE(WriteReply)
Q_DECLARE_METATYPE(ReadRndReply)
Q_DECLARE_METATYPE(ReadBlockReply)
然后我这样处理它:
class Task: public QObject{
public:
//c-tor and some functions, virtual functions etc
template <class TReply> bool applyReply(TReply reply){
varReply = QVariant::fromValue(reply);
}
auto getData(){ //here I should return data from tuple inside reply.
QVariant::Type t = varReply.type();
auto l = varReply.value<t>();// t is not a constexp // t is not a reply type but enum QVariant::type, as I understand.
return l.getData(); // l has no method getData
}
QVariant varReply; //this is the qvariant that contains templated reply;
}
我想念 QVariant 中的一些东西。我认为注册类型应该以某种方式存储在 Qvariant 中,但事实并非如此。其他问题:我不能使用c++17;它将用于许多具有不同回复签名的项目。有没有办法保留这些类型并在将来添加它们而无需完全重构?我考虑过某种经理class,但我可能想多了
QVariant
仅包含 Qt 中使用的内置类型的有用类型信息。如果有其他类型,需要在别处记录
class Task: public QObject{
public:
template <class TReply> bool applyReply(TReply reply){
varReply = QVariant::fromValue(reply);
}
template <class TReply> TReply getData(){reply.
return varReply.value<TReply>();
}
QVariant varReply;
}
void usesWriteTask() {
Task task;
task.applyReply(WriteReply());
// ...
WriteReply back = tast.getData<WriteReply>();
}
或者,如果您可以使用 boost,则可以使用 boost::variant
,这激发了 std::variant
class Task: public QObject{
public:
using VarReply = boost::variant<ReadRegReply, WriteReply, ReadRndReply, ReadBlockReply>;
bool applyReply(VarReply reply) {
varReply = reply;
}
template <class Result> Result getData(boost::static_visitor<Result> & visitor) {
return varReply.apply_visitor(visitor);
}
VarReply varReply;
}