For example, I'm trying to implement an AST using std::variant
, where a Token can be a number, keyword, or variable. Where numbers are represented by the int
and keywords and variables are represented by std::string
:
enum TokenType : std::size_t {
Number = 0, Keyword = 1, Variable = 2,
};
using Token = std::variant<int, std::string, std::string>;
Token token(std::in_place_index<TokenType::Variable>, "x");
When I want to do something with token
, I can first determine its type with token.index()
and then decide what to do:
switch (token.index()) {
case TokenType::Number:
return do_sth_with_number(std::get<TokenType::Number>(token));
case TokenType::Keyword:
return do_sth_with_keyword(std::get<TokenType::Keyword>(token));
case TokenType::Variable:
return do_sth_with_variable(std::get<TokenType::Variable>(token));
}
However, I don't know if I can use std::visit
to achieve the same effect. I only know that it can call specific function depending on the type of data in the variant, but I don't know if it is possible to do this depending on the index.
I know I can accomplish my goal by wrapping Keyword and Variable in two different classes, but I'm wondering if there's a better way to do it, because as I understand it, in variant, it should be more straightforward to decide which function to use based on the index rather than the type.
TokenType
enum altogether. The type of the token is the alternative held by the variant. No reason to save that same information in two different places. – Dougdougalstd::visit
? One that forwards index and the variable. – Altairstd::visit
dispatches the call based on the index but in all cases it calls the same visitor. So no, you cannot usestd::visit
if the visitor depends on the index, not just type. – Fecesstd::variant<Number, Keyword, Variable>
– Molleestd::visit
that callsfoo(index, var)
orfoo<index>(var)
rather thanfoo(var)
. The implementation is pretty much the same asstd::visit
, one just needs to forward the index in addition. – Altair