C++:显式调用模板参数的typedef的析构函数

gma*_*dau 5 c++ destructor typedef

我有以下内容:

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
    }
}; 
Run Code Online (Sandbox Code Playgroud)

这不会编译,说

限定类型与析构函数名称不匹配

typename在通话之前使用关键字也不起作用.但是,以下编译:

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

有人可以向我解释为什么,有没有办法让没有typedef

Fly*_*see 5

你应该使用不同的方式调用析构函数

x.Y::_X::~_X()
Run Code Online (Sandbox Code Playgroud)

以下编译对我来说很好:

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,这对Clang不起作用.我想知道这是一个错误,还是有一些模糊的规则,为什么它形成了不良. (2认同)

Pas*_* By 4

x.~Y::_X(); // This doesn\'t work\n
Run Code Online (Sandbox Code Playgroud)\n\n

是一个语法错误,我相信编译器将其解析为_X调用~Y

\n\n

在第二种情况下,当您调用包含的析构函数\xe2\x80\xa0时::时,最后两个类型名称必须表示相同的类型

\n\n
s.A::~B();\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中AB必须是同一类型。AB都在先前说明符指定的范围内查找(如果有)

\n\n
x._X::~_X();     // error, can\'t find _X in current scope\n
Run Code Online (Sandbox Code Playgroud)\n\n

逻辑上的修复是

\n\n
x.Y::_X::~_X();           // error, _X is dependent name\nx.typename Y::_X::~_X();  // error, typename cannot be here\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于Y::_X是一个从属名称typename因此需要消除它作为类型的歧义,但析构函数的语法不允许typename表达式中包含 a 。最终结果是您必须使用类型别名

\n\n
using X = typename Y::_X;\nx.~X();\n
Run Code Online (Sandbox Code Playgroud)\n\n

另一方面,编写并忘记析构函数调用的最简单方法就是

\n\n
x.~decltype(x)();\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是 gcc 和 msvc 无法编译它。

\n\n

\xe2\x80\xa0 更准确地说,伪析构函数调用

\n