Get the size of std::any
Asked Answered
G

2

6

Is there any way to get the size (in bytes) of the data stored by std::any? The only workaround I came up with is querying the type of its value by std::any::type and comparing the result to a list of known types like my_any.type() == typeid(T), then the size is sizeof(T). Unfortunately, this solution only works when the types are known beforehand.

Do you know any solution?

Goings answered 9/4, 2018 at 10:24 Comment(1)
This question is clear and well asked, regardless of the comments, and does not deserve such down voting. (Giving a need for any::size() does not much improve the question, tough it may help to expose XY problems.)Savick
S
6

You cannot get the size of the object held by std::any (other than the workaround you've mentioned). std::any is a minimal implementation of type erasure.

If you want something more powerful, write it yourself (it's not hard, just model it on std::any or boost::any and add the size() functionality). There are many other things you may want to add to any, such as I/O, storing multiple data (or the contents of any container) as arrays, etc..

At the expense of an additional data member (to store the size), you may also extend std::any by writing a wrapper, as suggested in Vittorio's answer.

Savick answered 9/4, 2018 at 10:35 Comment(0)
F
6

std::any does not provide any way of performing an action on the underlying stored type T. However, information like sizeof(T) could be available when initializing/assigning to std::any.

One possible solution is creating your own wrapper around std::any that keeps track of the size. E.g.

class my_any : std::any
{ 
    std::size_t _stored_size = 0;

public:
    template <typename T>
    my_any(T&&) : _stored_size{sizeof(std::decay_t<T>)} { }

    // ...
};
Freehold answered 9/4, 2018 at 10:34 Comment(7)
Probably better to use std::optional<std::size_t> than std::optional<int> since sizeof gives a result of type std::size_t.Laterite
Why do we need std::optional? Can we just use pure std::size_t?Strangeness
@DeanSeo std::size_t seems a better alternative to me also.Goings
@Dean what if the any is empty?Freehold
Then the size can be 0 no? Saves a boolean, which after alignment is not nothing.Caesar
@Caesar The size should be 1 instead? Not sure, but in case for my_any[]?Strangeness
@VittorioRomeo Right but even if there's a std::optional used, you'd still need to branch its initialization?Strangeness
S
6

You cannot get the size of the object held by std::any (other than the workaround you've mentioned). std::any is a minimal implementation of type erasure.

If you want something more powerful, write it yourself (it's not hard, just model it on std::any or boost::any and add the size() functionality). There are many other things you may want to add to any, such as I/O, storing multiple data (or the contents of any container) as arrays, etc..

At the expense of an additional data member (to store the size), you may also extend std::any by writing a wrapper, as suggested in Vittorio's answer.

Savick answered 9/4, 2018 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.