Search code examples
c++stdanyanycast

Does std::any_cast call destructor? How the cast works?


#include <iostream>
#include <any>

using namespace std;

class c {
public:
    c() :a{ 0 } { cout << "constructor\n"; }
    c(int aa) :a{ aa } { cout << "Constructor\n"; }
    ~c() { cout << "destructor\n"; }
    int get() { return a; }
private:
    int a;
};

auto main()->int
{
    any a{ 5 };
    cout << any_cast<int>(a) << '\n';
    
    a.emplace<c>(3);
    cout << '!' << any_cast<c>(a).get() << '\n';
    //des
    cout << '\n';
    
    a.emplace<c>(9);
    cout << '!' << any_cast<c>(a).get() << '\n';
    //des
}

destructor called after each any_cast. and, below code makes run-time error. I think the cause is any_cast(C)'s work pipeline is might be like ~C() then X(C) ERROR!!C doesn't exist any_cast really work like that?

I add blow codes and make run-time error.

class X {
public:
    X() :a{ 0 } { cout << "xonstructor\n"; }
    X(c& aa) :a{ aa.get() } { cout << "Xonstructor\n"; }
    ~X() { cout << "Xdestructor\n"; }
    int get() { return a; }
private:
    int a;
};

auto main()->int
{
    any a{ 5 };
    cout << any_cast<int>(a) << '\n';
    
    a.emplace<c>(3);
    cout << '!' << any_cast<X>(a).get() << '\n';
//runtime error after '!'
    cout << '\n';
    
    a.emplace<c>(9);
    cout << '!' << any_cast<X>(a).get() << '\n';
}

Solution

  • You are copying a c (or X) from the one within the std::any. That copy is destroyed at the end of the expression, after having been streamed out.

    any_cast does not do any conversion. It throws if you ask it for a type different to the one it stores. When you have emplaced a c and asked for an X, it throws std::bad_any_cast, because X is not c.