get currently held typeid of std::variant (like boost::variant type())

不问归期 提交于 2019-12-06 09:37:43
template<class V>
std::type_info const& var_type(V const& v){
  return std::visit( [](auto&&x)->decltype(auto){ return typeid(x); }, v );
}

Alternatively

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]);
}

Which lets you ask about other indexes that are not active.

The problem is that the currently-selected type is known only at runtime, whereas "obtaining" a type must be done at compile-time. This is exactly why we have visitors — to hide away the unavoidable chain of if statements behind the variant implementation.

Instead of re-inventing that implementation, it would be best to perform your map dispatching from inside such a visitor.

Failing that, you will have to write your own chain of if statements, producing code that's similar to the use of a visitor, but probably slower and less maintainable!

It is true that you can't implement such a thing by reading index() then asking the variant to give you equivalent typeid, as you could with the Boost implementation. But I'm pretty sure that's deliberate, because (as I've suggested above) any code making use of that would be ill-advised. Of course, if you really wanted to, you could write a visitor to produce such a typeid! But then you still have to write conditional logic to deal with that value, when you could have just put the logic into the visitor in the first place.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!