Оператор разыменования структуры (operator->) - PullRequest
9 голосов
/ 16 декабря 2011

Я пишу тонкий шаблон-оболочку для итераторов и наткнулся на камень преткновения при прохождении через оператор разыменования структуры, главным образом потому, что у указателей его нет:

#include <vector>

struct mystruct {
    int member;
};

template<class iterator>
struct wrap {
   typedef typename std::iterator_traits<iterator>::pointer pointer;
   iterator internal;
   pointer operator->() {return internal.operator->();} //MARK1
};

int main() {
    wrap<std::vector<mystruct>::iterator> a;
    a->member;
    wrap<mystruct*> b;
    b->member;
    return 0;
}

http://ideone.com/XdvEz

prog.cpp: In member function ‘typename std::iterator_traits<_Iter>::pointer wrap<iterator>::operator->() [with iterator = mystruct*]’:
prog.cpp:18:   instantiated from here
prog.cpp:11: error: request for member ‘operator->’ in ‘((wrap<mystruct*>*)this)->wrap<mystruct*>::internal’, which is of non-class type ‘mystruct*’

Этот следующий метод работает, но я не думаю, что он гарантированно работает.А именно, если итератор имеет странный тип pointer, который отличается от указателя на value_type.

   pointer operator->() {return &*internal;} //MARK3

1 Ответ

10 голосов
/ 16 декабря 2011

Стандарт косвенно говорит, что перегруженный operator-> должен либо возвращать указатель, либо объект, который можно преобразовать в указатель, либо объект, который перегружен operator->.Лучше всего просто вернуть internal.

§13.5.6 [over.ref] p1

Выражение x->m интерпретируется как (x.operator->())->m

(Вышесказанное применяется рекурсивно.)

...