How to explicitly call a namespace-qualified destructor?

前端 未结 2 1770
野趣味
野趣味 2021-01-03 20:04

I am surprised that the following simple code won\'t compile (with gcc, version 4.8.1)

#include 
void test()
{
  std::string* p = new std::stri         


        
相关标签:
2条回答
  • 2021-01-03 20:12

    2019 update: Starting from C++17, you can use std::destroy_at as follows:

    std::destroy_at(p);
    

    It's much simpler and follows the principle of not using "primitive constructs" (such as new / delete expressions) in modern C++.

    0 讨论(0)
  • 2021-01-03 20:26

    In the standard, at:

    §3.4.5/3

    If the unqualified-id is ~type-name, the type-name is looked up in the context of the entire postfix-expression.

    therefore it would seem that ~string should be looked up in the context of the std:: namespace.

    In fact, considering that a corresponding home-made version works as follows on both GCC and Clang:

    namespace STD {
    class STRING {};
    }
    
    int main() {
        STD::STRING* a = new STD::STRING();
        a->~STRING();
    }
    

    Live demo with clang++ Live demo with g++

    I'll go ahead and say this is most likely a bug.


    Apparently, given that std::string is really std::basic_string<char> if you call:

    a->~basic_string();
    

    Live demo with clang++ Live demo with g++

    then everything compiles fine.

    I still remain of the idea that this a bug, considering that the following example (taken from the standard), shows that typedefs should also work:

    struct B {
        virtual ~B() { }
    };
    
    struct D : B {
        ~D() { } 
    };
    
    D D_object;
    
    typedef B B_alias;
    
    B* B_ptr = &D_object;
    
    void f() {
    D_object.B::~B();
        B_ptr->~B();
        B_ptr->~B_alias();
        B_ptr->B_alias::~B();
        B_ptr->B_alias::~B_alias();
    }
    

    This notion, together with §3.4.5/3 should guarantee that:

    p->~string();
    

    should work.

    0 讨论(0)
提交回复
热议问题