Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to manually call destructor of std::string

Tags:

c++

I'm experimenting with unions and made this example class A with anonymous union member. Since the union contains a std::string and a std::vector I needed to define a destructor for the class. But, when I try to manually call ~string() I get

union.cpp: In destructor 'A::~A()':
union.cpp:14:14: error: expected class-name before '(' token
    s_.~string();

I don't get this with the vector. If I remove the call to s._~string(); it compiles fine. Is this a compiler bug? I'm using MinGW64.

#include <string>
#include <vector>

class A
{
    public:
    explicit A(const std::string &s) : s_ {s}, is_string {true} {}
    explicit A(const std::vector<int> &v) : v_ {v}, is_string {false} {}

    ~A()
    {
        if (is_string)
            s_.~string();
        else
            v_.~vector();
    }

    private:
    union
    {
        std::string s_;
        std::vector<int> v_;
    };
    bool is_string;

};

int main()
{
    A a("Hello, World!");
    return 0;
}

Using std::delete_at(std::addressof(s_)) does work with -std=c++17. What's going on here?

like image 692
dav Avatar asked Apr 28 '19 16:04

dav


People also ask

Can you manually call a destructor in C++?

Yes, it is possible to call special member functions explicitly by the programmer.

Can I call destructor manually?

Never call an object's destructor directly. The garbage collector will call it for you. The garbage collector maintains a list of objects that have a destructor. This list is updated every time such an object is created or destroyed.

How do you call a destructor forcefully?

Use the obj. ~ClassName() Notation to Explicitly Call a Destructor Function. Destructors are special functions that get executed when an object goes out of scope automatically or is deleted by an explicit call by the user.

How do you call a destructor in C++?

A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete . A destructor has the same name as the class, preceded by a tilde ( ~ ). For example, the destructor for class String is declared: ~String() .


1 Answers

std::string is not a real type but a typedef.

using std::string = std::basic_string<char>;

So you need to call basic_string destructor.

~A()
{
    if (is_string)
        s_.~basic_string();
    else
        v_.~vector();
}
like image 68
user6556709 Avatar answered Oct 05 '22 20:10

user6556709