Search code examples
c++initializationvariant

How to direct initialize a C++ variant with one of its non-default option?


Consider the following:

class Foo {
    [...]
public:
    Foo(int);
}

class Bar {
    [...]
public:
    Bar(int);
}

using MyVariant = std::variant<Foo,Bar>;

How can one direct initialize (i.e no copy and no Foo building involved) an instance of MyVariant as a Bar ?


Solution

  • Pass the a tag of type std::in_place_type_t<Bar> as first constructor parameter:

    struct Foo
    {
        Foo(int value)
        {
            std::cout << "Foo(" << value << ")\n";
        }
    };
    
    struct Bar
    {
        Bar(int value)
        {
            std::cout << "Bar(" << value << ")\n";
        }
    
        Bar(Bar const&)
        {
            std::cout << "Bar(Bar const&)\n";
        }
        Bar& operator=(Bar const&)
        {
            std::cout << "Bar& operator=(Bar const&)\n";
        }
    };
    
    int main() {
        std::variant<Foo, Bar> var(std::in_place_type_t<Bar>{}, 1);
    }
    

    std::in_place_index_t would be an alternative first parameter, if you prefer passing the position of the type in the template parameter list of std::variant.