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>使用模板,即
像f.template〜foo< int>,编译器必须假设你的析构函数
不是模板.
原路返回.
进一步,
6 A template-ID that names a class template specialization is a class-name (clause 9).
所以〜foo< int>命名你的模板专业化foo< int>因此是一个类名,
一个类名是由语法规则的一个类型名称,一个〜后面是一个typename
一个析构函数调用.因此
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>范围内,它是有效的
用foo来指代它.
这个标准实际上是明确的这个话题,哦.
最后,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]总结
以上是内存溢出为你收集整理的c – 模板化语境中的显式析构函数全部内容,希望文章能够帮你解决c – 模板化语境中的显式析构函数所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)