0

This question is related to Type erasing type erasure, `any` questions?

Given the class wstr below (just a string wrapper)

class wstr {
public:
    std::string text;
};

I have an any...

std::any myAny({myWstr});

..and I want to cast (convert) it to a string..

std::string myString = std::any_cast<std::string>(myAny);

... Is there a means of doing this by using template specialization, or (as I suspect) is this missing the point of using std::any?

This question is not about implicit conversion. I was thinking that I may need to write a friend function/overloading the cast, similar to writing ostream operator extensions.

Another way of asking this would be: Am I correct in thinking an std::any_cast does NOT CAST to anything, but rather ONLY CASTS a std::any back to it's original form, and therefore one cannot overload a function that supports the cast to eg, std::string, and is not available (for some reason) for friend function overloading / template specialization?

wstr myWstr("foo");
std::any myAny({myWstr});
wstr myWstr = std::any_cast<wstr>(myAny); //is okay.
std::string mMytr = std::any_cast<std::string>(myAny); //No overloads!
Konchog
  • 1,920
  • 19
  • 23
  • 4
    See my [question](https://stackoverflow.com/q/49428018/6205379) on the subject a while back. You cannot any_cast to another type. – Timo Jan 22 '19 at 12:17
  • 7
    `std::any` is wrong, because [`std::any`](https://en.cppreference.com/w/cpp/utility/any) isn't a template. Are you perhaps thinking about [`std::variant`](https://en.cppreference.com/w/cpp/utility/variant) or [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional)? – Some programmer dude Jan 22 '19 at 12:19
  • Possible duplicate of [why doesn't std::any\_cast support implicit conversion?](https://stackoverflow.com/questions/49428018/why-doesnt-stdany-cast-support-implicit-conversion) – xMutzelx Jan 22 '19 at 12:21
  • 5
    afaik `any_cast` is not really to cast between different types but merely to access the value stored in the `any` in a typesafe manner – 463035818_is_not_an_ai Jan 22 '19 at 12:26
  • 1
    here are some examples: https://en.cppreference.com/w/cpp/utility/any – 463035818_is_not_an_ai Jan 22 '19 at 12:27
  • There is some sample code to convert between wide and narrow strings here: https://stackoverflow.com/questions/51210723/how-to-detect-â€-combination-of-unicode-in-c-string/51212415#51212415 – Paul Sanders Jan 22 '19 at 12:30
  • btw I think what you actually need is a conversion not a cast – 463035818_is_not_an_ai Jan 22 '19 at 12:46
  • 2
    It does indeed look like you are missing the point of std::any. What are you trying to achieve exactly? And what do you think std::any does? – Dan M. Jan 22 '19 at 13:10
  • Sorry folks - I have edited the question to be more clear. This isn't about implicit conversion, but rather I was thinking of function overloading. – Konchog Jan 22 '19 at 13:14
  • @Timo, No - I am asking a slightly different question. This was more about how to overload / specialise the any_cast function, and did not expect dynamic casting. – Konchog Jan 22 '19 at 13:29
  • 2
    @Konchog: The thing is, you shouldn't *want to* "overload/specialize" `any_cast`. If that's what you want to do, then you are probably using `any` outside of its intended use case and purpose. – Nicol Bolas Jan 22 '19 at 14:24
  • @NicolBolas, yes - normally one wouldn't ever dream of it. I am using this in a visitor class where I am dealing with tokens after a parse. The purpose is really just to save from having to test for whitespace (what the wstr is) via type when I want to treat it as text. It's a bit complex to explain -everything- so I tried (vainly) to put it into a tiny case. But you are right... of course.. – Konchog Jan 22 '19 at 14:46

1 Answers1

0

The example given for any_cast at cppreference shows that casting an int to a std::string results in bad_any_cast exception being thrown.

The result will be the same if any_cast is used to convert wstr to std::string.

And BTW, std::any<wstr> myAny; does not work, since std::any is a class and not a template.

Instead you can test it this way:

#include <string>
#include <iostream>
#include <any>

class wstr {
public:
    std::string text;
};

int main()
{
    wstr ws;
    auto a = std::any(ws);

    try {
        std::cout << std::any_cast<std::string>(a) << '\n';
    }
    catch(const std::bad_any_cast& e) {
        std::cout << e.what() << '\n';
    }
}

See demo here.

P.W
  • 26,289
  • 6
  • 39
  • 76
  • Thanks, but due to the poverty of my initial question, this misses the point.. the point I was making was concerning extending/overloading std::any_cast, not expecting it to do the cast as it stands. – Konchog Jan 22 '19 at 13:30
  • @Konchog: then you will have to write your own conversion function, constructor or operator. `std::any_cast` is not the way to do it. – P.W Jan 23 '19 at 04:13