Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ std::variant vs std::any

Tags:

c++

c++17

C++17 presents std::variant and std::any, both able to store different type of values under an object. For me, they are somehow similar (are they?).

Also std::variant restricts the entry types, beside this one. Why we should prefer std::variant over std::any which is simpler to use?

like image 612
masoud Avatar asked May 25 '19 10:05

masoud


People also ask

What is std :: variant in C++?

The class template std::variant represents a type-safe union. An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value (this state is hard to achieve, see valueless_by_exception).

What is std :: any?

Defined in header <any> class any; (since C++17) The class any describes a type-safe container for single values of any copy constructible type. 1) An object of class any stores an instance of any type that satisfies the constructor requirements or is empty, and this is referred to as the state of the class any object.

Does std :: variant allocate memory?

According to cppreference ::std::variant must not allocate dynamic memory.

Does STD variant require RTTI?

Since this function is specific to a given type, you don't need RTTI to perform the operations required by std::any .


1 Answers

The more things you check at compile time the fewer runtime bugs you have.

variant guarantees that it contains one of a list of types (plus valueless by exception). It provides a way for you to guarantee that code operating on it considers every case in the variant with std::visit; even every case for a pair of variants (or more).

any does not. With any the best you can do is "if the type isn't exactly what I ask for, some code won't run".

variant exists in automatic storage. any may use the free store; this means any has performance and noexcept(false) issues that variant does not.

Checking for which of N types is in it is O(N) for an any -- for variant it is O(1).

any is a dressed-up void*. variant is a dressed-up union.

any cannot store non-copy or non-move able types. variant can.

The type of variant is documentation for the reader of your code.

Passing a variant<Msg1, Msg2, Msg3> through an API makes the operation obvious; passing an any there means understanding the API requires reliable documentation or reading the implementation source.

Anyone who has been frustrated by statically typeless languages will understand the dangers of any.

Now this doesn't mean any is bad; it just doesn't solve the same problems as variant. As a copyable object for type erasure purposes, it can be great. Runtime dynamic typing has its place; but that place is not "everywhere" but rather "where you cannot avoid it".

like image 189
Yakk - Adam Nevraumont Avatar answered Oct 05 '22 21:10

Yakk - Adam Nevraumont