Calum McManus
Calum McManus

Reputation: 260

Casting std::any back to its original type?

Is there a way to cast std::any back to its original type without having to hard code it?

I know you can do

std::any_cast<int>(example)

But this requires you do already know that "example" is an int. I noticed that std::any stores the original type but I can't seem to find anyway to use it for casting. I want to do something like this:

static_cast<example.type()>(example);

Sorry if this is a bit of a basic question but I feel like this may just not be possible and wanted to check.

Upvotes: 7

Views: 3463

Answers (2)

 blackshadow
blackshadow

Reputation: 77

I'm also thinging about this recently. We hope std::any has a method to get the original type instend of returning type_info. But this can not be implemented now unless C++ add the dynamic feature or runtime reflection like Java.

But I come up with a workaround. We store the "operation" in std::function instead of storing data in std::any.

Suppose we want to store different data and print and write them to file later.

//Solution1 use std::any
temlate<typename... T>
std::vector<std::any> prepare_data(T... t);
auto data=prepare_data(10,-1,0.5,3.3,"abcd",....); 
//....
void print_and_write(std::vector<std::any> data)
{
  for (....)
  {
     print(...)
     write(...)
  }
}
//Solution2 use std::function
temlate<typename... T>
std::vector<std::function<void(void)>> prepare_data(T... t);
auto operation=[](auto data){print(data);write(data);};
auto data=prepare_data(
         std::bind(operation,10),
         std::bind(operation,3.3),
         std::bind(operation,"abcd"),
         ...........
); 

void print_and_write(std::vector<std::function<void(void)>> data)
{
    for(...)
    {
        data[i]();//perform the lambda
    }
}

Upvotes: 0

bolov
bolov

Reputation: 75727

No, because the type of the cast must be known at compile time and the type held in a std::any instance is known at runtime.

I want to point here that std::any use cases are very very limited. You should probably never use it in an end-user facing code. Its role is a type safe alternative to void*. One use case that I can think of is in the implementation of some type-erasure class where previously void* would have been used (something like std::function maybe).

Think carefully if std::any is really what you need.

Upvotes: 11

Related Questions