получить текущий typeid типа std :: option (например, boost :: variable type ()) - PullRequest
0 голосов
/ 10 декабря 2018

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

Я использовал замечательную функцию в boost 'type ()', которая позволяет вам получить текущий typeid.См. 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 :: variable для индексации в списке типов варианта?Примерно так: Как получить N-й тип из кортежа?

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018
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]);
}

, что позволяет запрашивать другие неактивные индексы.

0 голосов
/ 10 декабря 2018

Проблема в том, что выбранный в данный момент тип известен только во время выполнения, тогда как «получение» типа должно быть сделано во время компиляции.Именно поэтому у нас есть посетители - чтобы скрыть неизбежную цепочку операторов if, стоящих за реализацией variant.

Вместо того, чтобы заново изобретать эту реализацию, было бы лучше выполнить диспетчеризацию вашей карты извнутри такого посетителя.

Если это не удастся, вам придется написать собственную цепочку операторов if, создающих код, похожий на использование посетителя, но, вероятно, более медленный и менее обслуживаемый!

Это правда, что вы не можете реализовать такую ​​вещь, прочитав index(), затем попросив вариант дать вам эквивалент typeid, как вы могли бы с реализацией Boost.Но я почти уверен, что это умышленно, потому что (как я уже говорил выше) любой код, использующий это, будет опрометчивым.Конечно, если бы вы действительно хотели, вы могли бы написать посетителю, чтобы создать такой typeid!Но тогда вам все равно придется написать условную логику, чтобы справиться с этим значением, когда вы могли бы просто поместить логику в посетителя.

...