2013-10-06 3 views
5

Я хочу сохранить какой-то контейнер, где тип сопоставляется с одним значением типа. Так что, по сути, я хочу, чтобы std::map<std::typeindex, T>, где T зависит от типа, с которым я индексирую его. std::map не похож на хороший способ сделать это, потому что типы жесткие. Какое простейшее решение я могу использовать для этого?Реестр данных различных типов

+0

Существует ли фиксированный набор типов для 'T'? –

+2

Вы можете нанести на карту 'boost :: any' возможно? –

+0

@ Даниэль Фрей: Да. Но я не хочу повторять что-то. Объявление того, что тип 'A' принадлежит' T', является, по-моему, повторением объявления типа 'A'. – user2852456

ответ

4

Если карта в контейнер типа стертым как boost::any, вы можете по крайней мере восстановить тип, если вы знаете, что это такое:

std::map<std::typeindex, boost::any> m; 

m[typeid(Foo)] = Foo(1, true, 'x'); 

Foo & x = boost::any_cast<Foo&>(m[typeid(Foo)]); 
+0

Какие преимущества у этого есть над чем-то вроде 'void *'? – user2852456

+3

@ user2852456: Попробуйте написать его с 'void *' и сравните! –

+0

@ user2852456: Хорошо, это может быть трудно оценить, но вы можете убедиться, что решение, которое я представляю, не имеет UB, тогда как тот, который вы собираетесь писать, будет намного более хрупким. –

2

Вы можете использовать shared_ptr<void>:

std::map<std::typeindex, std::shared_ptr<void>> m; 
m[typeid(T)] = std::make_shared<T>(...); 
auto pT = std::static_pointer_cast<T>(m[typeid(T)]); // pT is std::shared_ptr<T> 

Или, конечно, вы бы добавили некоторую оболочку, чтобы убедиться, что два T s на строку соответствуют друг другу, и вы случайно не получаете доступ к пустому shared_ptr<void>.

+0

Это решение выглядит синтаксически красивым (и +1 для этого), но следует отметить, что вы также оплачиваете цену стирания типа здесь, но вы также платите за совместную семенную семантику без участия гонок, хотя это может и не быть быть желательным, а статический бросок требует дисциплины для создания четко определенного поведения. «Boost :: any_cast» по контрасту никогда не вызывает UB. –

+0

@KerrekSB Учитывая, что ОП немного расплывчато по поводу требований, я думаю, что все в порядке, что все мы предлагаем некоторые варианты, и ОП может анализировать и выбирать то, что лучше для него. (и, следовательно, +1 для вашего ответа) –

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