Search code examples
c++c++17sfmlvariant

How to access method of class stored in std::variant


I am trying to access method of class held in std::variant. Unfortunately it throws and following error:

class ’std::variant<A, int>’ has no member named ‘function’

Code:

class A {
private:
    int number = 0;
public:
    A() {};
    void function(int i) {
        number += i;
    }
};

// ... main ...
std::variant<A,B> array[4][4];

array[0][0] = A(){};
array[0][0].function(3);

I tried to read documentation however I still don't understand how or whether should I use std::get() and std::variants.index() to access the aforementioned method.

After some reading I tried doing something like this in loop:

std::size_t t=array[i][j].index();
std::get<t>(array[i][j]).function();

It still didn't work though. The error was:

note: candidate: template<class _Tp, class ... _Types> constexpr _Tp&& std::get(std::variant<_Types ...>&&)
     constexpr inline _Tp&& get(variant<_Types...>&& __v)

template argument deduction/substitution failed:

Solution

  • To initialize a value in std::variant you can use std::get, or since C++17, emplace():

    array[0][0].emplace<A>();
    

    To access a value, use std::get:

    std::get<A>(array[0][0]).function(3);
    

    In addition, the template argument of std::get must be known at compile-time, so std::get<t> when t is a variable, won't work. You can do it slightly differently, e.g. like this:

    std::size_t t = array[0][0].index();
    switch (t) {
    case 0:
        std::get<0>(array[0][0]).function(3);
    case 1:
        // . . .
    }