c++ - 从 QVariant 接收未知的模板化对象

标签 c++ qt templates qvariant

我有一个可变参数模板类,用于保存来自自己的网络类的答案

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;
}

关于c++ - 从 QVariant 接收未知的模板化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53608445/

相关文章:

qt - 无法启动 qlocalserver

c++ - 在 Qt 中使用库

c++ - 从嵌套在模板中的类派生时的编译问题

c++ - 使用相同的模板实现更多功能

c++ - "Objective-C is a superset of C more strictly than C++"到底是什么意思?

c++ - 可以以某种方式省略 `get_mpz_t()` 吗?

python - 在 C++ 和 Python 中使用蒙特卡罗方法计算看涨期权价格时价格差异显着?

c++ - 在 float 中读取,不知何故它被改变了

qt - QListWidgetItem 项目相互重叠

c++ - 编译器优化消除了隐式模板实例化,从而导致链接器错误