C++: Explicitly call destructor of template parameter's typedef

ぐ巨炮叔叔 提交于 2019-12-07 04:10:00

问题


I have the following:

template <typename X> struct A {
    typedef X _X;
};

template <typename Y> struct B { // Y is struct A
    typename Y::_X x;
    void call_destructor () {
        x.~Y::_X(); // This doesn't work
        x.Y::~_X(); // This as well
    }
}; 

which doesn't compile, saying that

qualified type does not match destructor name

Using the keyword typename before the call also does not work. However, the following does compile:

template <typename Y> struct B {
    typename Y::_X x;
    typedef typename Y::_X __X;
    void call_destructor () {
        x.~__X(); // This works
    }
};

Can someone explain to me why, and is there any way to make do without the typedef?


回答1:


x.~Y::_X(); // This doesn't work

Is a syntax error, I believe the compiler parses it as calling _X in ~Y

In the second case, when you call a destructor containing ::, the last two type names must denote the same type

s.A::~B();

where A and B must be the same type. A and B are both looked up in the scope specified by previous specifiers, if any

x._X::~_X();     // error, can't find _X in current scope

The logical fix would be

x.Y::_X::~_X();           // error, _X is dependent name
x.typename Y::_X::~_X();  // error, typename cannot be here

Since Y::_X is a dependent name, typename is required to disambiguate it as a type, but the grammar of destructors doesn't admit a typename within the expression. The end result is you must use a type alias

using X = typename Y::_X;
x.~X();

On the other hand the easiest way to write-and-forget a destructor call is simply

x.~decltype(x)();

but gcc and msvc fails to compile this.

† More precisely, a pseudo-destructor call




回答2:


You should call the destructor differently using

x.Y::_X::~_X()

The following compile fine for me:

template <typename X> struct A {
    typedef X _X;
};

template <typename Y> struct B { // Y is struct A
    typename Y::_X x;
    void call_destructor () {
       x.Y::_X::~_X(); // This as well
    }
}; 


int main(){
  B<A<int> > b;
  b.call_destructor();
}


来源:https://stackoverflow.com/questions/45873952/c-explicitly-call-destructor-of-template-parameters-typedef

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!