2014-02-06 4 views
3

Мне нужен эффективный способ хранения значений разных типов (int, float, QString или std :: string, bool) в одном из «универсальных» контейнеров, таких как QVariant.QVariant vs boost :: any vs boost :: variant

Я хочу архивировать меньше использования памяти.

Я предпочитаю контейнер, который не сохраняет тип внутреннего значения, потому что это накладные расходы.

Какой я должен использовать?

+2

Если вам действительно нужен контейнер, который не сохраняет тип внутреннего значения, вы можете использовать 'std :: unique_ptr '. Но объект такого типа означает «я ссылаюсь на некоторые важные данные, которые вы больше не знаете, как читать», поэтому для меня это кажется бессмысленным. – gTcV

+1

Но можем ли мы проверить тип любого объекта с помощью инструкции 'typeid', не так ли? –

+2

@ Виталий Исаев. Главное требование состоит в том, что использование 'typeid' неявно означает, что вы должны включить' RTTI'. Также такие решения основаны на методах стирания типа C++, и я не знаю, насколько это повлияет на способность вашего «RTTI» дать правильный ответ. Например, http://stackoverflow.com/questions/5450159/type-erasure-techniques – user2485710

ответ

-1

Я столкнулся с подобным вопросом около года назад. Я не помню рассуждений, но я пошел с толчком: любой. boost: любой хранит тип, который можно использовать для извлечения значения в формате желания.

Вот пример:

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

Надеется, что это помогает !!

3

boost::any может содержать значения любого типа, но вы должны знать, что он может удержать, чтобы извлекать значение и выделяет память в куче для сохраненного значения.

boost::variant с другой стороны, может хранить только значение набора определенных типов, и вы можете легко выяснить, что она держится, sizeof из boost::variant собирается быть sizeof наибольшего типа значения содержит + некоторые дополнительными для типа хранимого значения, поскольку он не использует кучную память (если не используется рекурсивный вариант).

С точки зрения использования памяти точка зрения boost::variant может быть более эффективной, поскольку она не использует кучную память. Кроме того, boost::variant более безопасен по типу, который boost::any, компилятор может найти больше ошибок во время компиляции для вас.

Смежные вопросы