Получить текущий typeid типа std::variable (например, boost::variable type())

Я перешел с boost:: многоадресного варианта на стандартный: и попал в ловушку.

Я использовал симпатичную функцию в boost 'type()', которая позволяет вам получить текущий typeid. См. https://www.boost.org/doc/libs/1_48_0/doc/html/boost/variant.html

Как этого добиться с помощью std:: option?

У меня есть неупорядоченный ключ карты в 'type_index', который содержит некоторое значение 'std:: function'. Мой вариант, в зависимости от типа, будет определять, какую функцию я выберу с карты для выполнения какой-либо операции. (Код, который у меня есть, слишком велик для публикации).

Любые идеи реализации помимо написания конкретного посетителя для конкретного std:: варианта? Может быть, с помощью функции index() в std:: variable для индексации в списке типов варианта? Примерно так: Как получить N-й тип из кортежа?

2 ответа

Решение
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! Но тогда вам все равно придется написать условную логику, чтобы справиться с этим значением, когда вы могли бы просто поместить логику в посетителя в первую очередь.

Другие вопросы по тегам