加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 在std :: vector上扩展成员选择运算符` – >`的实现是否

发布时间:2020-12-16 10:00:46 所属栏目:百科 来源:网络整理
导读:问题 如果value_type是指针类型,那么成员选择运算符 – 迭代器是无用的,因为间接是访问成员所必需的:(* _It) – 成员.如果有代码执行类似_It- method()的操作,则将包含项的类型更改为指针类型会变得麻烦. 这是因为成员选择运算符的原始实现 – 是: // retu
问题

如果value_type是指针类型,那么成员选择运算符 – >迭代器是无用的,因为间接是访问成员所必需的:(* _It) – >成员.如果有代码执行类似_It-> method()的操作,则将包含项的类型更改为指针类型会变得麻烦.

这是因为成员选择运算符的原始实现 – >是:

// return pointer to class object
pointer operator->() const { return (&**this); }

提出的解决方案

如果value_type是指针类型,则成员选择运算符应返回引用而不是指针.

详细说明实施:
我刚刚在< utility>中插入了后续扩展名.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读