c – 模板化语境中的显式析构函数
我想在模板化的上下文中显式地销毁一个向量.以下为我工作(GNU C 4.3,4.4和Clang 1.1):
template <typename T> void destroy_vector_owner(VectorOwner<T> *obj) { obj->v.~vector(); // further cleanup by Python API functions omitted } 而在Mac OS X v10.5的g(i686-apple-darwin10-gcc-4.2.1)上,它失败了 expected class-name before ‘(’ token 如果我把它改成 obj->v.~vector<T>(); 代码无法用G编译,但Clang仍然可以处理它.哪个是正确的成语?这些编译器是否已知在这方面被破坏? 更新:VectorOwner的定义是 template <typename T> struct VectorOwner { PyObject_HEAD std::vector<T> v; }; 这是一个Python对象,必须保持一个std :: vector.我承认构造是有点危险的,但是我需要紧凑型存储,分摊O(1)push_back,并且能够使用交换成员来窃取另一个向量的内容. 解决方法
我的第一个答案实际上是错误的,litb指出我的方向正确.正确的答案是
这两种语法都是正确的: 析构函数调用语法. 12.4析构函数中描述了一个显式析构函数调用的语法: 12 In an explicit destructor call,the destructor name appears as a ? followed by a type-name that names the destructor’s class type. The invocation of a destructor is subject to the usual rules for member functions (9.3) [...] 类型名称可以在7.1.5.2中找到简单类型说明符: type-name: class-name enum-name typedef-name 类名称在9中描述.类: class-name: identifier template-id 所以一个析构函数调用是简化的,以下之一 foo.~typedef-name () foo.~identifier () foo.~template-id () 我们这里没有typedef名称,也没有一个简单的标识符,所以只有foo.?template-id()留下 编译器对使用模板参数的析构函数调用的假设. 我们也在14.模板 3 After name lookup (3.4) finds that a name is a template-name,if this name is followed by a <,the < is always taken as the beginning of a template-argument-list and never as a name followed by the less-than operator. 所以编译器必须在你的例子中假定<是开始 另外,如果你的析构函数是一个模板(…),那么 4 When the name of a member template specialization appears after . or -> in a postfix-expression,or after nested-name-specifier in a qualified-id,and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2),the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template. 所以因为你没有前缀你的析构函数调用f.?foo< int>使用模板,即 原路返回. 进一步, 6 A template-id that names a class template specialization is a class-name (clause 9). 所以?foo< int>命名你的模板专业化foo< int>因此是一个类名, foo<int> f; f.~foo<int>(); // valid 析构函数调用没有模板参数. 但也 f.~foo(); // valid 因为3.4.5类成员访问: 3 If the unqualified-id is ?type-name,and the type of the object expression is of a class type C (or of pointer to a class type C),the type-name is looked up in the context of the entire postfix-expression and in the scope of class C. [...] 因此在f.?foo(); foo在f.中查找,并且在foo< int>范围内,它是有效的 这个标准实际上是明确的这个话题,哦. 最后,14.3包含一个全然的权限: 5 An explicit destructor call (12.4) for an object that has a type that is a class template specialization may explicitly specify the template-arguments. [Example: template<class T> struct A { ?A(); }; void f(A<int>* p,A<int>* q) { p->A<int>::?A(); // OK: destructor call q->A<int>::?A<int>(); // OK: destructor call } —end example] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |