代码之家  ›  专栏  ›  技术社区  ›  Moia

是否有一种方法可以转换存储在qvariant中的基类型而不专门化cast?

  •  3
  • Moia  · 技术社区  · 8 年前

    让我们考虑这个例子:

    QVariant v1(1);
    QVariant v2("goofy");
    QVariantList list;
    
    list << v1 << v2;
    
    for (const auto& var : list) {
       qdebug() << var;
    
       // nasty part
       if (var.type == QVariant::Int) {
          int value = var.toInt();
    
          // do something
       } else if (var.type == QVariant::QString) {
          QString value = var.toString();
    
          // do something
       }
    }
    

    debug函数显示 q-变体 :

    QVariant(int, 1) QVariant(QString, "goofy") 
    

    有没有办法避免 if 并执行显式强制转换以访问内部类型?更具体地说,为了得到这个值,我希望能够写这样的东西:

    auto value = var.ToData();
    

    编辑 :因为qvariant可以容纳很多类型,甚至可以在其上添加自定义类型,所以仅将问题限制为基类型就足够了。 (int,double,bool,string)

    2 回复  |  直到 8 年前
        1
  •  4
  •   Jaa-c    8 年前

    不,这是不可能的。作为任何其他变体, QVariant 基本上是一个联盟。除非你知道数据的类型,否则你无法得到它。如果你想象的代码 auto value = var.ToData(); 应该工作,类型 value 在编译时必须是可解析的,但之后就不会是变量了。

    变量的全部意义在于,它允许您在一个值中存储多个类型,所有这些都在运行时完成。在内部,它存储其值的类型,但它是一个运行时值-因此,如果您不确切地知道类型,除了进行长切换之外,没有其他方法。

        2
  •  0
  •   Kuba hasn't forgotten Monica    8 年前

    这是可能的,但代价是 QVariant 不这样做。有两种相关方法:

    1. q-变体 可以在运行时将所有运算符分派到特定于类型的运算符,例如添加两个 q-变体 包含整数的可以调用 int operator+(int,int) . 这并不是因为很难用一种足够通用的方式来完成,但是如果你有一些类型的想法,你当然可以做你自己的类型来完成它。它可以在内部使用 q-变体 但我不愿意把它作为 q-变体 . 它可以转换成 q-变体 但是,这样您就可以在需要变量的地方传递类型,但不能让它本身是变量——即使用组合,而不是继承。

    2. q-变体 无法实现模板化类型转发,该转发将使用sfinae和模板表达式根据对其执行的操作推断类型,并替换对其执行的操作 q-变体 对包含的类型执行的操作,没有运行时开销。写出一个足够具体的表达式将推断出类型,如果它不够具体,那么您就必须提供类型提示——就像在任何函数语言中使用类型推断一样。

    当您有一个小的类型列表时,任何一种方法都可以很好地工作,但是有过多的类型 q-变体 必须支持-包括a-priori未知用户类型-一般的方法有这么多的限制,以至于无法使用。在不知道你如何处理这些价值观的情况下很难判断。当一个描述的简洁程度低于 //do something .

    推荐文章