Why can I not retrieve the index of a variant and use that to get its content?

Why can I not retrieve the index of a variant and use that to get its content?

std::variant
std::visit

I'm trying to access the content of a variant. I don't know what's in there, but thankfully, the variant does. So I thought I'll just ask the variant what index it is on and then use that index to std::get its content.

But this does not compile:

#include <variant>

int main()
{
  std::variant<int, float, char> var { 42.0F };

  const std::size_t idx = var.index();

  auto res = std::get<idx>(var);

  return 0;
}

The error happens in the std::get call:

error: no matching function for call to ‘get<idx>(std::variant<int, float, char>&)’
   auto res = std::get<idx>(var);
                               ^
In file included from /usr/include/c++/8/variant:37,
                 from main.cpp:1:
/usr/include/c++/8/utility:216:5: note: candidate: ‘template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)’
     get(std::pair<_Tp1, _Tp2>& __in) noexcept
     ^~~
/usr/include/c++/8/utility:216:5: note:   template argument deduction/substitution failed:
main.cpp:9:31: error: the value of ‘idx’ is not usable in a constant expression
   auto res = std::get<idx>(var);
                               ^
main.cpp:7:15: note: ‘std::size_t idx’ is not const
   std::size_t idx = var.index();
               ^~~

How can I fix this?


Essentially, you cannot.

You wrote:

I don't know what's in there, but thankfully, the variant does

... but only at run-time, not at compile-time.And that means your idx value is not compile-time.And that means you can't use get<idx>() directly.

Something you could do is have a switch statement; ugly, but it would work:

switch(idx) {
case 0: { /* code which knows at compile time that idx is 0 */ } break;
case 1: { /* code which knows at compile time that idx is 1 */ } break;
// etc. etc.
}

This is rather ugly however. As comments suggest, you might as well std::visit() (which is not very different from the code above, except using variadic template arguments instead of being this explicit) and avoid the switch altogether. For other index-based approaches (not specific to std::variant), see:

Idiom for simulating run-time numeric template parameters?

Everything You Need to Know About std::variant from C++17, Extra Content! You don't have a way to know what's the currently used type and what's intFloatString); // index will show the currently used 'type' std::cout It's just an empty type that can be used with variants to represent empty state. In short: use the actual types you store inside a variant so that no� You are using a regex against the literal text \clist_item:Nn\myList{\int_use:N\myCounter}, not the result of executing it. In the case where you use an explicit 1, that works, but not when you have no 1 present. Fixing that by expansion, and also using standard variable names plus a step loop (seems easier here), I'd have


The compiler needs to know the value of idx at compilation time for std::get<idx>() to work, because it is being used as a template argument.

First option: If the code is meant to run at compile time, then make everything constexpr:

constexpr std::variant<int, float, char> var { 42.0f };

constexpr std::size_t idx = var.index();

constexpr auto res = std::get<idx>(var);

This works because std::variant is constexpr friendly (its constructors and methods are all constexpr).

Second option: If the code is not meant to run at compile time, which is likely the case, the compiler cannot deduce at compile time the type of res, because it could be three different things (int, float or char). C++ is a statically-typed language, and the compiler must be able to deduce the type of auto res = ... from the expression that follows (i.e. it must always be the same type).

You can use std::get<T>, with the type instead of an index, if you already know what it will be:

std::variant<int, float, char> var { 42.0f }; // chooses float

auto res = std::get<float>(var);

In general, use std::holds_alternative to check if the variant is holding each of the given types, and handle them separately:

std::variant<int, float, char> var { 42.0f };

if (std::holds_alternative<int>(var)) {
    auto int_res = std::get<int>(var); // int&
    // ...
} else if (std::holds_alternative<float>(var)) {
    auto float_res = std::get<float>(var); // float&
    // ...
} else {
    auto char_res = std::get<char>(var); // char&
    // ...
}

Alternatively you can use std::visit. This is slightly more complicated: you can use a lambda/templated function that is type-agnostic and works for all of the variant's types, or pass a functor with an overloaded call operator:

std::variant<int, float, char> var { 42.0f };

std::size_t idx = var.index();

std::visit([](auto&& val) {
    // use val, which may be int&, float& or char&
}, var);

See std::visit for details and examples.

std::get (std::variant), The call is ill-formed if I is not a valid index in the variant. 2) Type-based value accessor: If v holds the alternative T , returns a reference to the� 10 Why can I not retrieve the index of a variant and use that to get its content? Nov 29 '19. 6 Python: How to make this color thresholding function more efficient


The problem is that std::get<idx>(var); require (for idx) a compile time known value.

So a constexpr value

// VVVVVVVVV
   constexpr std::size_t idx = var.index();

But to initialize idx as constexpr, also var had to be constexpr

// VVVVVVVVV
   constexpr std::variant<int, float, char> var { 42.0F };

FAQ about using ClinVar and understanding its data display, How can I retrieve batches of data from ClinVar? ClinVar doesn't have Why do some variants in ClinVar have no genomic location? Is a new version Click on Show index list to the righ of that menu. Descriptions of There are several options you can use to display the contents of the file: Use FireFox. You can probably already see how these two work together. MATCH finds the row containing the data and then INDEX looks left or right across the row to retrieve the data a column in that row. When used together they look like this, =INDEX(array,MATCH(lookup_value,lookup_array,[match_type]),[column_num]) The functions used in the example are,


The problem arises from templates being instantiated at compile-time while the index you are getting is calculated at run-time. Similarly, C++ types are also defined at compile-time so even with the auto declaration, res must have a concrete type for the program to be well-formed. This means that even without the restriction on the template, what you are trying to do is inherently impossible for non-constant expression std::variants. How would one work around this?

Firstly, if your variant is indeed a constant expression, the code compiles and works as expected

#include <variant>

int main()
{
  constexpr std::variant<int, float, char> var { 42.0f };

  constexpr std::size_t idx = var.index();

  auto res = std::get<idx>(var);

  return 0;
}

Otherwise you will have to use some manual branching mechanism

if (idx == 0) {
    // Now 'auto' will have a concrete type which I've explicitly used
    int value == std::get<0>(var);
}

You could define these branches using the visitor pattern, see std::visit.

Variant Manager Overview, Marketplace; Browse � Submit Content � Marketplace FAQ � Marketplace Guidelines If the Actor you modified was not already bound to the selected Variant, it is Switching on Variants that you identify by name or by index. Use the Get Variant or Get Variant By Name node to retrieve a Variant from its index or its name. While retrieving all the data from the resultset, we can not enforce all the original column names to be unique. This is just the reason, why we can set column-aliases. When retrieving data via index-access "res.getXXX(int)", all is fine. But while retrieving using the name-variant "res.getXXX(String name)", we should use here the _alias_ as name.


This is inherently impossible in C++’s model; consider

template<class T> void f(T);
void g(std::variant<int,double> v) {
  auto x=std::get<v.index()>(v);
  f(x);
}

Which f is being called, f<int> or f<double>? If it’s "both", that means that g contains a branch (which it doesn’t), or that there are two versions of g (which just pushes the problem onto its caller). And think about f(T,U,V,W)—where does the compiler stop?

There is actually a proposal for a JIT for C++ that would allow things like this by compiling those additional versions of f when they’re called, but it’s very early.

The Ultimate Guide To Collections in Excel VBA, If you have used the language for any length of time then you will have used Collections. Access all items(For Each), Dim fruit As Variant Enter your email to get the fully documented VBA code for this post plus exclusive content not available on the website To Access the items of a collection you simply use the index. If you want to retrieve the data from every column in a table, you do not need to specify each column name after the SELECT keyword. Use the asterisk character (*) in place of a column list in a SELECT statement to instruct MySQL to return every column from the specified table. The following query retrieves every column and row from the


Excel VBA Array - The Complete Guide, The rest of the post provides the most complete guide you will find on the VBA array. Set Size, See Declare above, ReDim arr(0 To 5)As Variant Enter your email to get the fully documented VBA code for this post plus exclusive content not If we use ReDim on an existing array, then the array and its contents will be � I used bcftools to get a subset of the vcf file (hereafter B.vcf.gz). I'm now trying to use isec to find the differences between the two files as such: bcftools isec A.vcf.gz B.vcf.gz -n -1 -c all. This command generates the following error: [add_reader] Could not load the index of A.vcf.gz. I have the idx file for A.vcf.gz in the working


Arrays, 6.4.2.1 Excel function 'Index' You can retrieve an element from a 2-dimensional array using the serial number in each dimension; e.g. You can find a cell specifying its horizontal dimension (row) and its vertical dimension (column): If you do not specify the array's content it will be a Variant by default. Samtools checks the current working directory for the index file and will download the index upon absence. Samtools does not retrieve the entire alignment file unless it is asked to do so. COMMANDS. Each command has its own man page which can be viewed using e.g. man samtools-view or with a recent GNU man using man samtools view. Below we have


Excel, VBA and Variant Arrays, And it's not just VBA that starts to slow things down - large worksheets that are The key to this is to use variant arrays to grab all the data from a woksheet or content of comments, style or other attribute then using a variant array doesn't gain above example the code cycles through every cell to get to calculate the sum. Basically, you are trying to get a specific row number in your table. There is no SQL equivalent (at least a simple way) to get this. Adding the .ToList() you are forcing an immediate execution of the query and bring the results into memory, specifically into a List object. This has a nice easy way to access the data via an index.