Barry gave us this gorgeous get_index
for variants:
template <typename> struct tag { };
template <typename T, typename V>
struct get_index;
template <typename T, typename... Ts>
struct get_index<T, std::variant<Ts...>>
: std::integral_constant<size_t, std::variant<tag<Ts>...>(tag<T>()).index()>
{ };
To be used as follows:
using V = variant<A, B, C>;
constexpr const size_t N = get_index<B, V>::value; // 1
It works great in Clang (OSX).
But in Visual Studio 2017 I'm getting the following:
<source>(10): error C2039: 'index': is not a member of 'std::variant<tag<Ts>...>'
<source>(10): note: see declaration of 'std::variant<tag<Ts>...>'
<source>(11): note: see reference to class template instantiation 'get_index<T,std::variant<_Types...>>' being compiled
Compiler returned: 2
I can't see why. Any ideas?
(Full disclosure: in my project I'm actually using mpark::variant
because I have been using Xcode 9, which didn't have std::variant
. However, you can see from the Godbolt MCVE above that this affects the implementation with std::variant
as well. I'm convinced the problem is either in the code above, or in the compiler.)
get_index<B, V>::value
is 1. – Beckon{}}
contains an unmatched}
– Rectorstd::variant<tag<Ts>...>{tag<T>{}}.index()
(braces instead round parentheses) we get a different error: "<source>(12): error C2440: 'initializing': cannot convert from 'initializer list' to 'std::variant<tag<Ts>...>' <source>(12): note: The target type has no constructors". Using the same contruct in other places (inmain()
, by example) gives no error. – Wenoaconstexpr
function of typestd::size_t()
, but not for aconstexpr auto
function (compiler nonsensically claims that theauto
function is used before it is defined). – Lightyear/Permissive-
flag since it changes the code path taken inside the compiler devblogs.microsoft.com/cppblog/… – Idiomatic