我有以下内容:
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
}
};
不编译,说
限定类型与析构函数名称
不匹配
在通话之前使用关键字typename
也不起作用。但是,以下编译:
template <typename Y> struct B {
typename Y::_X x;
typedef typename Y::_X __X;
void call_destructor () {
x.~__X(); // This works
}
};
有人可以向我解释为什么,如果没有typedef
,有没有办法可以做到?
答案 0 :(得分:5)
您应该使用
以不同方式调用析构函数x.Y::_X::~_X()
以下编译对我来说很好:
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();
}
答案 1 :(得分:3)
x.~Y::_X(); // This doesn't work
是语法错误,我相信编译器将其解析为在_X
中调用~Y
在第二种情况下,当您调用包含::
的析构函数†时,最后两个类型名称必须表示相同的类型
s.A::~B();
其中A
和B
必须是同一类型。 A
和B
都在前面的说明符指定的范围内查找,如果有的话
x._X::~_X(); // error, can't find _X in current scope
逻辑修复将是
x.Y::_X::~_X(); // error, _X is dependent name
x.typename Y::_X::~_X(); // error, typename cannot be here
由于Y::_X
是dependent name,因此typename
需要将其作为一种类型消除歧义,但析构函数的语法不允许表达式中包含typename
。最终结果是您必须使用类型别名
using X = typename Y::_X;
x.~X();
另一方面,编写并忘记析构函数调用的最简单方法就是
x.~decltype(x)();
但是gcc和msvc无法编译它。
†更准确地说,是一个伪析构函数调用