У пользовательского operator->
есть особенность, что он ведет себя так, как будто operator->
рекурсивно вызывается для возвращаемого значения. Таким образом, учитывая T some_type::operator->() const
, это ведет себя как:
some_type()->some_member;
// moral equivalent:
some_type()::operator->()->some_member;
Обычно этого не замечают, потому что при попытке вернуть простой указатель, так что после первого operator->
используется встроенный ->
и, следовательно, цепочка имеет глубину только 1. Похоже, что вы можете использовать это поведение для своих нужд, используя:
SmartVertexHandle<Mesh> SmartVertexIterator<Mesh>::operator->();
и
SmartVertexHandle<Mesh>* SmartVertexHandle<Mesh>::operator->()
{ return this; }
Затем, когда пользователь делает wrapper.VerticesBegin()->Position()
, VerticesBegin()
возвращает SmartVertexIterator
, первый operator->
возвращает SmartVertexHandle
, а второй, неявный, operator->
возвращает указатель на этот временный дескриптор, где встроенный ->
звонки SmartVertexHandle::Position
. Предположительно умная ручка сконструирована и предназначена для того, чтобы знать, как делать parent->GetVertexPosition(parent->GetVertexHandle( ... ) )
. Затем, когда вычисляется полное выражение, временное SmartVertexHandle
изящно исчезает.
Обратите внимание, что я повторно использовал ваши имена для SmartVertexHandle
& SmartVertexIterator
, но у меня нет возможности узнать, могут ли ваши классы быть (пере) спроектированы для такого использования. В идеальном мире я бы не обязательно разработал бы отдельную SmartVertexHandle
для пользователя; Я бы, вероятно, написал бы тип SmartVertexIterator::proxy
для возврата operator->
, а затем использовал бы описанную выше технику.
В целом, я думаю, что ваш текущий подход к сохранению дескриптора - это нетерпеливая версия, где дескриптор вычисляется и сохраняется всякий раз, когда создается итератор, и, предположительно, пересчитывается всякий раз, когда итератор, например ,. увеличивается. Мой подход - более ленивая версия, создающая дескриптор только по запросу (но не сохраняющая его и перестраивающая его каждый раз, даже когда итератор идентичен). Я не думаю, что первый «довольно ужасен», так как я не знаю, как дорого создавать дескрипторы по сравнению с итераторами, или как часто дескрипторы разыменовываются / используются для каждого шага итератора. Третий подход может быть даже ленивее.
В обоих случаях я бы посоветовал не показывать пользователю SmartVertexHandle
(конечно, может быть, у вас есть требования).