Q:

Is it correct to extend the implementation of the member selection operator `->` of iterators on std::vector?

Problem
If value_type is a pointer type, then the member selection operator -> of an iterator is useless because the indirection is required to access a member: (*_It)->member. And if there is code doing something like _It->method(), changing the type of contained items to a pointer type becomes trouble.
This is because the original implementation of the member selection operator -> is:
// return pointer to class object
pointer operator->() const { return (&**this); }

Proposed solution
If value_type is a pointer type, the member selection operator should return reference instead of pointer.
Elaborated implementation:
I've just inserted the followning extension into <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 ref, 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; }
};

I've replaced the original implementation of the member selection operator -> in <vector> for _Vector_const_iterator and _Vector_iterator by my extended implementation:
typename ref_or_ptr<value_type, reference, pointer>::res
operator->() const {
    return (ref_or_ptr<value_type, reference, pointer>::get(**this));
}

And now, the following became possible, preserving the original behavior of the member selection operator:
#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;
}

Output:
s_i: 1
p_i: 1

Two questions
Yes, replacing the original implementation of STL templates is a bad thing if the code should be compiled by someone else. It could be solved by providing the extended versions of <utility> and <vector>, if the copyright owner or license allows that. Otherwise it will be impossible to distribute such software.

So, is it correct to extend the original implementation of the member selection operator on a pointer in the described way? In case of in-house software, it is probably correct. And it is not, if the source code should be open or used by someone who cannot get these extended versions. What are such cases? Are there other cases?
Are there cases when the proposed extended implementation will not function?

A:

You don't need to write any code for this--Boost already has it!  See here: http://www.boost.org/doc/libs/1_59_0/libs/ptr_container/doc/tutorial.html
Their example:
typedef boost::ptr_vector<animal>  ptr_vec;
ptr_vec vec;
ptr_vec::iterator i = vec.begin();
i->eat(); // no indirection needed

