tmporaries
tmporaries

Reputation: 1553

QVariant vs boost::any vs boost::variant

I need efficient way to store values of different types (int, float, QString or std::string, bool) in one of "generic" containers like QVariant.

I want to archive less memory usage.

I prefer a container that doesn't store type of the internal value because it is an overhead.

Which one should I use?

Upvotes: 3

Views: 3547

Answers (2)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136505

boost::any can hold values of any type, but you have to know what it can possibly hold to be able to extract the value and it allocates memory on the heap for the stored value.

boost::variant on the other hand, can only store values of a set of specified types and you can easily find out what it holds, the sizeof of boost::variant is going to be the sizeof of the largest value type it contains + some extra for the type of the stored value because it does not use heap memory (unless a recursive variant is used).

From memory usage standpoint of view boost::variant may be more efficient because it does not use heap memory. Also, boost::variant is more type-safe that boost::any, the compiler can find more errors at compile time for you.

Upvotes: 3

Ankit Patel
Ankit Patel

Reputation: 1223

I've faced similar question about a year ago. I don't remember the reasoning but I've gone with the boost:any. boost:any does store the typeid that can be used to retrieve the value in desire format.

Here is an example:

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

Hope this helps!!

Upvotes: -1

Related Questions