Подтвердить что ты не робот

Почему `boost:: any` лучше, чем` void * `?

Какие присущие преимущества предлагают boost::any и boost::any_cast с использованием void* и dynamic_cast?

4b9b3361

Ответ 1

Преимущество состоит в том, что boost::any является более безопасным для типов, чем void*.

например.

int i = 5;
void* p = &i;
static_cast<double*>(p);  //Compiler doesn't complain. Undefined Behavior.
boost::any a;
a = i;
boost::any_cast<double>(a); //throws, which is good

Что касается вашего комментария, вы не можете dynamic_cast от void*. Вы можете dynamic_cast только из указателей и ссылок на типы классов, которые имеют по крайней мере одну виртуальную функцию (также называемую полиморфными типами)

Ответ 2

boost::any вызывает деструкторы:

{
    boost::any x = std::string("Hello, world");
    x = std::wstring(L"Goodbye"); // string::~string called here
} // wstring::~wstring called here

Ответ 3

как-то никто не упоминал, что boost:: any < > действует как тип значения, где void * является указателем. Это означает, что любой < > может хранить ЛЮБОЙ объект любого размера. После сохранения вы можете передать переменную любого типа < > в любом месте; он живет на собственном опыте.

С другой стороны, void * имеет размер указателя, поэтому вам нужно либо удостовериться, что sizeof (ваши данные) <= sizeof (void *) или ваш void * - это просто указатель на реальные данные, которые хранятся где-нибудь еще. Но в этом случае он полностью отличается от любого < > , потому что теперь вам нужно беспокоиться об этом "где-то еще" и убедиться, что он остается действительным до тех пор, пока void * действителен, что иногда может стать проблемой, особенно в многопоточных приложениях.

Плюс, поскольку другие упомянули, что какой-либо < > является очень безопасным по типу, он сохранит все, что вы хотите, но единственный способ вернуть его - знать точный тип или он не работает (что может быть любопытным, когда один API дает вам unsigned int и ваш код хочет, чтобы int обрабатывались как разные типы). void * позволит вам делать все, что вам нужно, и если вы начнете читать или прокладывать кучу и/или неинициализированную память, это не остановит вас и даже не сообщит вам, что вы это делаете.

Ответ 4

Вот что говорит ссылка на ускорение:

Он поддерживает копирование любого типа значения и безопасное выделение это значение строго против его типа.

Ни один из них не может быть выполнен с помощью void*. Для вас нет чеков, и вы должны сами знать, к чему вы можете их отнести.

Я не думаю, что dynamic_cast вообще входит в изображение, так как он напрямую не имеет ничего общего с этим.