c – 在std :: vector上扩展成员选择运算符` – >`的实现是否
问题
如果value_type是指针类型,那么成员选择运算符 – >迭代器是无用的,因为间接是访问成员所必需的:(* _It) – >成员.如果有代码执行类似_It-> method()的操作,则将包含项的类型更改为指针类型会变得麻烦. 这是因为成员选择运算符的原始实现 – >是: // return pointer to class object pointer operator->() const { return (&**this); } 提出的解决方案 如果value_type是指针类型,则成员选择运算符应返回引用而不是指针. 详细说明实施: template<typename val,typename ref,typename ptr> struct ref_or_ptr { // To know if value_type is a pointer enum {RES=false}; // By default,operator -> should return a pointer typedef ptr res; // return pointer // The translation function sould be used to return proper type // in both the cases,otherwise the complier results in the conversion error. static res get(ref v) { return &v; } }; // Specialization for the case when value_type is a pointer template<typename val,typename ptr> struct ref_or_ptr<val *,ref,ptr> { enum {RES=true}; // value_type is a pointer type typedef ref res; // return reference // In this case,the reference is returned instead of the pointer. // But here value_type is a pointer type,and the address-of operator is not needed: static res get(ref v) { return v; } }; 我已经取代了成员选择运算符的原始实现 – >在< vector>中对于我的扩展实现的_Vector_const_iterator和_Vector_iterator: typename ref_or_ptr<value_type,reference,pointer>::res operator->() const { return (ref_or_ptr<value_type,pointer>::get(**this)); } 现在,以下内容成为可能,保留了成员选择运算符的原始行为: #include <stdio.h> #include <tchar.h> #include <iostream> #include <vector> typedef struct udf { static int auto_m; int _m; udf(): _m(++auto_m) {} } * udf_ptr; int udf::auto_m = 0; int _tmain(int argc,_TCHAR* argv[]) { using namespace std; typedef vector<udf_ptr> udf_p_v; typedef vector<udf> udf_v; udf_v s(1); udf_p_v p(1); p[0] = &s[0]; udf_v::iterator s_i(s.begin()); udf_p_v::iterator p_i(p.begin()); // Now,the indirection on p_i is not needed // in order to access the member data _m: cout << "s_i: " << s_i->_m << endl << "p_i: " << p_i->_m << endl; return 0; } 输出: s_i: 1 p_i: 1 两个问题 是的,如果代码应该由其他人编译,则替换STL模板的原始实现是一件坏事.它可以通过提供< utility>的扩展版本来解决.和版权所有者或许可证允许的< vector>.否则将无法分发此类软件. >那么,以所描述的方式在指针上扩展成员选择运算符的原始实现是否正确?对于内部软件,它可能是正确的.如果源代码应该是开放的,或者是那些无法获得这些扩展版本的人使用的话,那就不是了.这种情况是什么?还有其他情况吗? 解决方法
你不需要为此编写任何代码 – Boost已经拥有它!见:
http://www.boost.org/doc/libs/1_59_0/libs/ptr_container/doc/tutorial.html
他们的例子: typedef boost::ptr_vector<animal> ptr_vec; ptr_vec vec; ptr_vec::iterator i = vec.begin(); i->eat(); // no indirection needed (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |