Я перешел с boost :: многоадресного варианта на стандартный: и попал в ловушку.
Я использовал симпатичную функцию в boost ‘type ()’, которая позволяет вам получить текущий idid. Увидеть https://www.boost.org/doc/libs/1_48_0/doc/html/boost/variant.html#id1752388-bb
Как этого добиться с помощью std :: option?
У меня есть неупорядоченный ключ карты в ‘type_index’, который содержит некоторое значение ‘std :: function’. Мой вариант, в зависимости от типа, будет определять, какую функцию я выберу с карты для выполнения какой-либо операции. (У меня слишком большой код для публикации).
Любые идеи по реализации помимо написания конкретного посетителя для конкретного std :: варианта? Может быть, с помощью функции index () в std :: варианте, чтобы затем внести индекс в список типов варианта? Примерно так: Как получить N-й тип из кортежа?
template<class V>
std::type_info const& var_type(V const& v){
return std::visit( [](auto&&x)->decltype(auto){ return typeid(x); }, v );
}
альтернативно
template<class...Ts>
std::type_info const& var_type(std::variant<Ts...> const& v, std::optional<std::size_t> idx={}){
if (!idx) idx=v.index();
if(*idx==std::variant_npos) return typeid(void);
const std::array<std::type_info const*, sizeof...(Ts)> infos[]={ &typeid(Ts)... };
return *(infos[*idx]);
}
Что позволяет вам спросить о других индексах, которые не активны.
Проблема в том, что текущий выбранный тип известен только во время выполнения, тогда как «получение» типа должно быть сделано во время компиляции. Именно поэтому у нас есть посетители — чтобы скрыть неизбежную цепь if
заявления за variant
реализация.
Вместо того, чтобы заново изобретать эту реализацию, было бы лучше выполнить диспетчеризацию вашей карты изнутри такого посетителя.
В противном случае вам придется написать свою собственную цепочку if
операторы, производящие код, похожий на использование посетителя, но, вероятно, более медленный и менее обслуживаемый!
Это правда, что вы не можете реализовать такую вещь, читая index()
затем попросить вариант дать вам эквивалент typeid
, как вы могли бы с реализацией Boost. Но я почти уверен, что это намеренно, потому что (как я уже говорил выше) любой код, использующий это, был бы опрометчивым. Конечно, если вы действительно хотите, вы могли бы написать посетителю, чтобы произвести такой typeid
! Но тогда вам все равно придется написать условную логику, чтобы справиться с этим значением, когда вы могли бы просто поместить логику в посетителя в первую очередь.