【问题标题】:QVariant vs boost::any vs boost::variantQVariant vs boost::any vs boost::variant
【发布时间】:2014-02-06 19:30:23
【问题描述】:

我需要有效的方法将不同类型的值(int、float、QString 或 std::string、bool)存储在像 QVariant 这样的“通用”容器之一中。

我想归档更少的内存使用。

我更喜欢不存储内部值类型的容器,因为这是开销。

我应该使用哪一个?

【问题讨论】:

  • 如果你真的想要一个不存储内部值类型的容器,你可以使用std::unique_ptr<void>。但是这种类型的对象意味着“我引用了一些你不再知道如何阅读的重要数据”,所以对我来说似乎毫无意义。
  • 但是我们可以用typeid指令检查任何对象的类型,不是吗?
  • @VitalyIsaev 的主要要求是使用typeid 隐含意味着您必须启用RTTI。此外,这种解决方案依赖于c++ type erasure 技术,我不知道这会在多大程度上影响您的RTTI 为您提供正确答案的能力。例如stackoverflow.com/questions/5450159/type-erasure-techniques
  • 正如here 所说,typeid 只有在您使用多态性时才能以您想要的方式工作。如果在void 指针上使用typeid,它将返回void*,如果在取消引用的void 指针上使用它,则程序不应编译,因为不允许取消引用void 指针.此外,即使它以您想要的方式工作,您提出的库也可能会使用 typeid 运算符实现。
  • @tmporaries 你基本上离“未定义行为主题公园”;使用unionvoid pointers,获得UB 非常容易,如果您真的知道自己在做什么,那么这种操作非常有用。如果您需要空间,请对内存中的内容使用压缩算法并保持简单。

标签: c++ boost boost-variant qvariant boost-any


【解决方案1】:

boost::any 可以保存任何类型的值,但是您必须知道它可以保存什么才能提取该值,并且它会在堆上为存储的值分配内存。

另一方面,boost::variant 只能存储一组指定类型的值,您可以轻松找出它所保存的内容,boost::variantsizeof 将是最大的sizeof它包含的值类型 + 一些额外的存储值类型,因为它不使用堆内存(除非使用递归变体)。

从内存使用的角度来看,boost::variant 可能更有效,因为它不使用堆内存。此外,boost::variantboost::any 更安全,编译器可以在编译时为您找到更多错误。

【讨论】:

    【解决方案2】:

    大约一年前我遇到过类似的问题。我不记得是什么原因了,但我已经有了提升:任何。 boost:any 确实存储了可用于以期望格式检索值的 typeid。

    这是一个例子:

    #include <iostream>
    #include <boost/any.hpp>
    #include <string>
    
    int main()
    {
        boost::any value;
    
        for(int i=0; i < 3; i++)
        {
            switch (i)
            {
            case 0:
                value = (double) 8.05;
                break;
            case 1:
                value = (int) 1;
                break;
            case 2:
                //std::string str = "Hello any world!";
                //value = str;
                value = std::string("Hello any world!");
                break;
            }
    
            if(value.type() == typeid(double))
                std::cout << "it's double type: " << boost::any_cast<double>(value) << std::endl;
            else if(value.type() == typeid(int))
                std::cout << "it's int type: " << boost::any_cast<int>(value) << std::endl;
            else if(value.type() == typeid(std::string))
                std::cout << "it's string type: " << boost::any_cast<std::string>(value) << std::endl;
        }
        return 0;
    }
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 2018-07-21
      • 1970-01-01
      相关资源
      最近更新 更多