Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

stl std::map's iterators operator ->

127 views
Skip to first unread message

Jeff Koftinoff

unread,
Mar 4, 2006, 9:29:16 AM3/4/06
to
I am writing my own associative container which has different execution
and memory tradeoffs compared to any map/hash in stl or boost.

I want the container to be compatible with std::map as much as
possible, so that it can be a 'drop-in' replacement for most users.

I notice that my g++ 4.0 installation's std::map's iterator classes
have an operator ->, which returns a pointer std::pair< key_type,
value_type >. But my container does not store the data as pairs, so
there is no pointer to return! Should I just not provide operator ->
and tell users of my container to do something different?

I can provide operator *, and construct a std::pair and return it. Is
it necessary for stl associative container iterators to return pairs?

Also, is there a comprehensive list anywhere of the official methods,
typedefs, and iterators that stl compliant containers MUST provide?
Many books I see are sorely lacking and only seem cover std::string
operator << and container's push_back().

Regards

Jeff Koftinoff

--
www.jdkoftinoff.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Alberto Ganesh Barbati

unread,
Mar 5, 2006, 8:35:59 AM3/5/06
to
Jeff Koftinoff ha scritto:

> I am writing my own associative container which has different execution
> and memory tradeoffs compared to any map/hash in stl or boost.
>
> I want the container to be compatible with std::map as much as
> possible, so that it can be a 'drop-in' replacement for most users.
>
> I notice that my g++ 4.0 installation's std::map's iterator classes
> have an operator ->, which returns a pointer std::pair< key_type,
> value_type >. But my container does not store the data as pairs, so
> there is no pointer to return! Should I just not provide operator ->
> and tell users of my container to do something different?
>
> I can provide operator *, and construct a std::pair and return it. Is
> it necessary for stl associative container iterators to return pairs?

For std::map the value_type is std::pair<const K, V> so if you want to
make a drop-in replacement, your container must keep the *same*
value_type, which is the type used for both inserting and returning
objects. /In theory/ you don't need to store elements as pairs, but you
definitely need to return them as pairs, so storing them as pairs is
probably your best choice.

About iterator::operator->, paragraph 24.1/1 says that "All iterators i
for which the expression (*i).m is well-defined, support the expression
i->m with the same semantics as (*i).m." So you are indeed required to
implement operator-> in a way that returns a pointer to pair. If you
need to build a pair on-the-fly, you might store it in the iterator
object itself, but that might make the iterator a heavy-weight object
and it would be undesirable.

> Also, is there a comprehensive list anywhere of the official methods,
> typedefs, and iterators that stl compliant containers MUST provide?
> Many books I see are sorely lacking and only seem cover std::string
> operator << and container's push_back().

The C++ Standard is there exactly for that purpose!

HTH,

Ganesh

David Abrahams

unread,
Mar 6, 2006, 6:04:14 AM3/6/06
to
"Jeff Koftinoff" <jeff.ko...@gmail.com> writes:

> I am writing my own associative container which has different execution
> and memory tradeoffs compared to any map/hash in stl or boost.
>
> I want the container to be compatible with std::map as much as
> possible, so that it can be a 'drop-in' replacement for most users.
>
> I notice that my g++ 4.0 installation's std::map's iterator classes
> have an operator ->, which returns a pointer std::pair< key_type,
> value_type >. But my container does not store the data as pairs, so
> there is no pointer to return! Should I just not provide operator ->
> and tell users of my container to do something different?
>
> I can provide operator *, and construct a std::pair and return it. Is
> it necessary for stl associative container iterators to return pairs?
>
> Also, is there a comprehensive list anywhere of the official methods,
> typedefs, and iterators that stl compliant containers MUST provide?

It seems you're really concerned about what an iterator should
provide. The required STL iterator interface is extremely difficult,
in general, to implement correctly. You should use
http://www.boost.org/libs/iterator/doc/iterator_facade.html or
http://www.boost.org/libs/iterator/doc/iterator_adaptor.html to get it
right. They'll take care of issues like the operator-> correctly for
you.

HTH,

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

kanze

unread,
Mar 6, 2006, 9:21:34 AM3/6/06
to
Alberto Ganesh Barbati wrote:
> Jeff Koftinoff ha scritto:
> > I am writing my own associative container which has
> > different execution and memory tradeoffs compared to any
> > map/hash in stl or boost.

> > I want the container to be compatible with std::map as much
> > as possible, so that it can be a 'drop-in' replacement for
> > most users.

> > I notice that my g++ 4.0 installation's std::map's iterator
> > classes have an operator ->, which returns a pointer
> > std::pair< key_type, value_type >. But my container does
> > not store the data as pairs, so there is no pointer to
> > return! Should I just not provide operator -> and tell users
> > of my container to do something different?

> > I can provide operator *, and construct a std::pair and
> > return it. Is it necessary for stl associative container
> > iterators to return pairs?

> For std::map the value_type is std::pair<const K, V> so if you
> want to make a drop-in replacement, your container must keep
> the *same* value_type, which is the type used for both
> inserting and returning objects. /In theory/ you don't need to
> store elements as pairs, but you definitely need to return
> them as pairs, so storing them as pairs is probably your best
> choice.

If I correctly understand the requirements in §23.1.2, in an
associative container, the value type must be either the same as
the key type, or an std::pair (but I find it somewhat difficult
to determine exactly what are abstract requirements for an
associative container, and what only applies to the associative
containers defined in the standard).

Also note that the operator* on the iterator must return a
reference, and that something like &(*iter).second is a
perfectly legal expression. Which creates not a few lifetime of
object problems is the actual container doesn't use pairs.

> About iterator::operator->, paragraph 24.1/1 says that "All
> iterators i for which the expression (*i).m is well-defined,
> support the expression i->m with the same semantics as
> (*i).m." So you are indeed required to implement operator-> in
> a way that returns a pointer to pair. If you need to build a
> pair on-the-fly, you might store it in the iterator object
> itself, but that might make the iterator a heavy-weight object
> and it would be undesirable.

It would also create problems concerning the lifetime of the
results. "V* pv = &iter->second" is a perfectly valid
expression, and the pointer pv is guaranteed valid as long as
the container exists and element has not been removed from it.

Also, if two iterators point to the same element, and I take the
address as above, the two addresses are guaranteed to be equal.
So any "cache" of the pair objects must be maintained by the
container itself, and not the iterator.

> > Also, is there a comprehensive list anywhere of the official
> > methods, typedefs, and iterators that stl compliant
> > containers MUST provide? Many books I see are sorely lacking
> > and only seem cover std::string operator << and container's
> > push_back().

> The C++ Standard is there exactly for that purpose!

Regretfully, it's not always as clear as it could be.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jeff Koftinoff

unread,
Mar 7, 2006, 6:46:29 AM3/7/06
to
Thanks for your response, James.

It appears that I must store an entire std::pair<const
key_type,mapped_type> in my leaf node in order to provide the
appropriate interface for the iterators.

It is kind of unfortunate that the it appears that the associative
container must hold a pair.

My container is a trie with a very memory hungry but very very fast
find { O(0) }, and having the leaf node hold a pair is redundant since
the key is actually stored in the pattern of connections travelled to
get to the leaf node.

As an experiment I wanted to take my pre-existing 'fast tree' example
code:

http://www.jdkoftinoff.com/main/Articles/Fast_Tree

And make it into a stl compliant container, allowing for any stl
sequence to be the key and allowing for any user class to be the value.
iterators are very tricky with this!

It is quite eye-opening to see the complexities of stl container
design. { Thank you David Abrahams for the boost information on the
iterator facade - that helps. }

Another thing I noticed is problematic is the organization of how the
allocator is passed and used. My trie_map template is currently
declared as:

template <
typename KEY_T,
typename MAPPED_T,
typename ALLOCATOR_T = std::allocator< std::pair< const KEY_T,
MAPPED_T> >
>
class trie_map {...};

But that ALLOCATOR_T is not the only allocations that are going on. my
trie_map needs to be able to recursively be able to create child
trie-maps. Currently, my trie_map just calls new to create new
trie_maps. But it should have a separate allocator for them. Then I
guess I have to supply two allocators to the template. I envision
something like:

template <
typename KEY_T,
typename MAPPED_T,
typename ALLOCATOR_T = std::allocator< std::pair< const KEY_T,
MAPPED_T> >,
typename TRIE_ALLOCATOR_T = std::allocator<
// here is the problem, this type would have to be self-referring
trie_map< KEY_T,MAPPED_T,ALLOCATOR_T,TRIE_ALLOCATOR_T>
>
>
class trie_map {...};

The only way I can envision around that problem is by having a run-time
performance hit. Or by not allowing a custom allocator for the trie
tables themselves.


Ultimately, what I am looking for is a set of code and tests that I can
compile against my container to see if it truly is
standards-conforming.

Regards,
Jeff

www.jdkoftinoff.com

kanze

unread,
Mar 7, 2006, 6:59:38 AM3/7/06
to

That's certainly true for the general case, but how can it do so
for his specific case: his container does NOT use std::pair
internally, and there is no way for a reference to std::pair to
designate something in the container. But as an associative
container, if I understand the requirements correctly,
dereferencing the iterator must 1) return a reference and 2) the
value_type must be either the key type, or std::pair.

Note that I recently had a similar problem. Because the code
was being compiled with a somewhat ancient version of Sun CC
(5.1), I couldn't use Boost, but a quick glace at
iterator_adaptor suggests that it doesn't have a solution
either. My problem was that dereferencing the iterator actually
called a member function on the object, which returned a value.
So I had nothing for the reference to refer to. I could have
cached the value in the iterator, and returned a reference to
that, but as John Potter pointed out, one of the requirements of
a forward iterator is that if p == q, then &*p == &*q (although
in practice, I doubt that any of the non-modifying algorithms
actually require this). I couldn't find a solution -- if Boost
has one, I'm all ears.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

David Abrahams

unread,
Mar 7, 2006, 7:43:45 PM3/7/06
to
"kanze" <ka...@gabi-soft.fr> writes:

> David Abrahams wrote:
>
>> It seems you're really concerned about what an iterator should
>> provide. The required STL iterator interface is extremely
>> difficult, in general, to implement correctly. You should use
>> http://www.boost.org/libs/iterator/doc/iterator_facade.html or
>> http://www.boost.org/libs/iterator/doc/iterator_adaptor.html
>> to get it right. They'll take care of issues like the
>> operator-> correctly for you.
>
> That's certainly true for the general case, but how can it do so
> for his specific case: his container does NOT use std::pair
> internally, and there is no way for a reference to std::pair to
> designate something in the container.

It's simple: if he wants operator* to return a pair (or, more likely,
a boost::tuple of references), his iterator can't be a forward
iterator.

> But as an associative container, if I understand the requirements
> correctly, dereferencing the iterator must 1) return a reference and
> 2) the value_type must be either the key type, or std::pair.

Right. If his iterators can't be forward iterators, his "container"
can't be associative (can't be a container even, IIRC).

> Note that I recently had a similar problem. Because the code
> was being compiled with a somewhat ancient version of Sun CC
> (5.1), I couldn't use Boost, but a quick glace at
> iterator_adaptor suggests that it doesn't have a solution
> either.

iterator_facade does have a solution for operator-> on input iterators
(and all the others that use proxies --- see "new iterator concepts")

> My problem was that dereferencing the iterator actually
> called a member function on the object, which returned a value.

input iterator.

> So I had nothing for the reference to refer to. I could have
> cached the value in the iterator, and returned a reference to
> that, but as John Potter pointed out, one of the requirements of
> a forward iterator is that if p == q, then &*p == &*q (although
> in practice, I doubt that any of the non-modifying algorithms
> actually require this). I couldn't find a solution -- if Boost
> has one, I'm all ears.

It has one in the new iterator concepts. Of course, your standard
algorithms may not be prepared to take advantage of those.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

kanze

unread,
Mar 8, 2006, 7:00:23 AM3/8/06
to
David Abrahams wrote:
> "kanze" <ka...@gabi-soft.fr> writes:

> > David Abrahams wrote:

> >> It seems you're really concerned about what an iterator should
> >> provide. The required STL iterator interface is extremely
> >> difficult, in general, to implement correctly. You should use
> >> http://www.boost.org/libs/iterator/doc/iterator_facade.html or
> >> http://www.boost.org/libs/iterator/doc/iterator_adaptor.html
> >> to get it right. They'll take care of issues like the
> >> operator-> correctly for you.

> > That's certainly true for the general case, but how can it
> > do so for his specific case: his container does NOT use
> > std::pair internally, and there is no way for a reference to
> > std::pair to designate something in the container.

> It's simple: if he wants operator* to return a pair (or, more
> likely, a boost::tuple of references), his iterator can't be a
> forward iterator.

I was afraid that was the answer:-).

> > But as an associative container, if I understand the
> > requirements correctly, dereferencing the iterator must 1)
> > return a reference and 2) the value_type must be either the
> > key type, or std::pair.

> Right. If his iterators can't be forward iterators, his
> "container" can't be associative (can't be a container even,
> IIRC).

> > Note that I recently had a similar problem. Because the
> > code was being compiled with a somewhat ancient version of
> > Sun CC (5.1), I couldn't use Boost, but a quick glace at
> > iterator_adaptor suggests that it doesn't have a solution
> > either.

> iterator_facade does have a solution for operator-> on input
> iterators (and all the others that use proxies --- see "new
> iterator concepts")

> > My problem was that dereferencing the iterator actually
> > called a member function on the object, which returned a
> > value.

> input iterator.

Except that the iterator was used as a parameter to
max_element:-).

In the case of non-const iterators, the why of this requirement
is obvious (and input iterators don't have it because they can't
be non-const). It the case of const iterators, it seems like
over specification -- I can't imagine an implementation of
max_element, for example, where returning an object (either
synthesized or a copy) would pose a problem.

> > So I had nothing for the reference to refer to. I could
> > have cached the value in the iterator, and returned a
> > reference to that, but as John Potter pointed out, one of
> > the requirements of a forward iterator is that if p == q,
> > then &*p == &*q (although in practice, I doubt that any of
> > the non-modifying algorithms actually require this). I
> > couldn't find a solution -- if Boost has one, I'm all ears.

> It has one in the new iterator concepts. Of course, your
> standard algorithms may not be prepared to take advantage of
> those.

What are the chances of the new iterator concepts becoming
standard?

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

David Abrahams

unread,
Mar 8, 2006, 11:43:23 AM3/8/06
to
"kanze" <ka...@gabi-soft.fr> writes:

>> > My problem was that dereferencing the iterator actually
>> > called a member function on the object, which returned a
>> > value.
>
>> input iterator.
>
> Except that the iterator was used as a parameter to
> max_element:-).

Too bad; the standard iterator concepts don't accomodate him.

> In the case of non-const iterators, the why of this requirement
> is obvious (and input iterators don't have it because they can't
> be non-const).

You mean "constant," not const (ugly and subtle distinction: see
http://www.boost.org/libs/iterator/doc/iterator_facade.html#a-constant-node-iterator).
And input iterators _can_ be mutable iterators (a model of input
iterator can also model output iterator).

> It the case of const iterators, it seems like
> over specification -- I can't imagine an implementation of
> max_element, for example, where returning an object (either
> synthesized or a copy) would pose a problem.

The problem is, again, the binding together of traversal and access in
the current iterator concepts. Only forward iterators (which includes
bidirectional and random access iterators) are guaranteed to be
multi-pass iterators. Since max_element needs to pass over the data
once to find the iterator to return, its result would be meaningless
without multi-pass capability, so the algorithm requires forward
iterators.

>> > So I had nothing for the reference to refer to. I could
>> > have cached the value in the iterator, and returned a
>> > reference to that, but as John Potter pointed out, one of
>> > the requirements of a forward iterator is that if p == q,
>> > then &*p == &*q (although in practice, I doubt that any of
>> > the non-modifying algorithms actually require this). I
>> > couldn't find a solution -- if Boost has one, I'm all ears.
>
>> It has one in the new iterator concepts. Of course, your
>> standard algorithms may not be prepared to take advantage of
>> those.
>
> What are the chances of the new iterator concepts becoming
> standard?

Heh, long and contentious story, which I'll tell from my POV. I'm
100% certain that others would have a different take on it.

They were initially accepted into TR1 but later pulled because some
LWG members had decided they were half-baked and the problem could be
solved much more simply. Some of us who worked on the issue were worn
down by the process of trying to convince people that we knew what we
were doing. Eventually those people who thought the concepts weren't
baked decided to try to address the problems, and soon discovered they
were going in all the same directions as our proposal. So then they
recruited a few of the original authors to work on it with them. Last
I heard, they were able to make one very small simplification to our
original proposal and were at an impasse about whether the concept
framework should allow move_iterator
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1859.html).

Meanwhile, I was tired of struggling with the iterator abstractions,
and decided it was time to solve the problem of traversal and access
being bound together once and for all, by accepting Dietmar Kuehl's
recommendation to use cursors and property maps. We brought
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1873.html
before the LWG, where it met with a rather cool response, I must say.
In the meantime, I keep finding places where the use of cursors and
property maps makes code much cleaner. Go figure.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Pete Becker

unread,
Mar 8, 2006, 4:58:08 PM3/8/06
to
David Abrahams wrote:
>
> They were initially accepted into TR1 but later pulled because some
> LWG members had decided they were half-baked and the problem could be
> solved much more simply.

There was nothing wrong with the ideas. The proposal just didn't hang
together. For example, the issues list for that proposal was far longer,
in proportion to the size of the proposal, than the issues list for
regular expressions, which had been under serious discussion far longer.
The proposal itself went through two major rewrites in the three months
after its initial acceptance. Getting it into shape would have delayed
TR1 for a year.

> Some of us who worked on the issue were worn
> down by the process of trying to convince people that we knew what we
> were doing.

Well, worn down by trying to quickly push out fixes to serious problems.

--

Pete Becker
Roundhouse Consulting, Ltd.

David Abrahams

unread,
Mar 9, 2006, 5:40:12 AM3/9/06
to
Pete Becker <peteb...@acm.org> writes:

> David Abrahams wrote:
>>
>> They were initially accepted into TR1 but later pulled because some
>> LWG members had decided they were half-baked and the problem could be
>> solved much more simply.
>
> There was nothing wrong with the ideas. The proposal just didn't hang
> together. For example, the issues list for that proposal was far longer,
> in proportion to the size of the proposal, than the issues list for
> regular expressions, which had been under serious discussion far longer.
> The proposal itself went through two major rewrites in the three months
> after its initial acceptance. Getting it into shape would have delayed
> TR1 for a year.
>
>> Some of us who worked on the issue were worn
>> down by the process of trying to convince people that we knew what we
>> were doing.
>
> Well, worn down by trying to quickly push out fixes to serious problems.

....and there you have it.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Steven E. Harris

unread,
Mar 9, 2006, 1:29:44 PM3/9/06
to
David Abrahams <da...@boost-consulting.com> writes:

> I was tired of struggling with the iterator abstractions, and
> decided it was time to solve the problem of traversal and access
> being bound together once and for all, by accepting Dietmar Kuehl's
> recommendation to use cursors and property maps. We brought
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1873.html
> before the LWG

I noticed that the syntax shown for property map access eschews the
current and previous implementations' use of free functions get(pm,
key) and put(pm, key, value), instead using the property map itself as
a function object.

What are the comparative advantages and disadvantages that made you
choose the latter approach? I recall (perhaps mistakenly) that the
get() and put() functions were preferred to unadorned accommodate
arrays as property maps.

--
Steven E. Harris

David Abrahams

unread,
Mar 10, 2006, 7:47:39 AM3/10/06
to
"Steven E. Harris" <s...@panix.com> writes:

> David Abrahams <da...@boost-consulting.com> writes:
>
>> I was tired of struggling with the iterator abstractions, and
>> decided it was time to solve the problem of traversal and access
>> being bound together once and for all, by accepting Dietmar Kuehl's
>> recommendation to use cursors and property maps. We brought
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1873.html
>> before the LWG
>
> I noticed that the syntax shown for property map access eschews the
> current and previous implementations' use of free functions get(pm,
> key) and put(pm, key, value), instead using the property map itself as
> a function object.

Yes.

> What are the comparative advantages and disadvantages that made you
> choose the latter approach?

Better interoperability with other code is a big advantage. There are
lots of function objects lying around that make great property maps.
For example, consider

std::bind2nd(std::multiplies<int>(), 3)

or, with Boost.Lambda,

_1*3

Now you have a "transform" property map that multiplies each key by 3.
And because there's so much code around for composing and currying
function objects, you can easily manipulate property maps that way.

A minor advantage is that you can use result_of<p(i)> to get the
result type of any property map access, without introducing yet
another trait.

> I recall (perhaps mistakenly) that the
> get() and put() functions were preferred to unadorned accommodate
> arrays as property maps.

I can't parse "...to unadorned accommodate arrays...," sorry.

I think you're referring to the fact that we can't overload operator()
for arrays directly. I think operating directly on arrays turned out
not to be so important; it's very easy to make a lightweight wrapper
that turns a pointer into a property map.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Sergey P. Derevyago

unread,
Mar 10, 2006, 8:48:23 AM3/10/06
to
David Abrahams wrote:
> Meanwhile, I was tired of struggling with the iterator abstractions,
> and decided it was time to solve the problem of traversal and access
> being bound together once and for all, by accepting Dietmar Kuehl's
> recommendation to use cursors and property maps. We brought
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1873.html
> before the LWG, where it met with a rather cool response, I must say.
> In the meantime, I keep finding places where the use of cursors and
> property maps makes code much cleaner. Go figure.
>
Great.
As you know, I also tried to explicitly pool a position indicator out of
iterator concept:
http://groups.google.com/group/comp.std.c++/msg/923710443bd99f0f
But found a problem on the way:
http://groups.google.com/group/comp.std.c++/msg/cbed1f06d92469a4
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net

Dietmar Kuehl

unread,
Mar 10, 2006, 8:43:10 AM3/10/06
to
Steven E. Harris wrote:
> I noticed that the syntax shown for property map access eschews the
> current and previous implementations' use of free functions get(pm,
> key) and put(pm, key, value), instead using the property map itself as
> a function object.

Yes.

> What are the comparative advantages and disadvantages that made you
> choose the latter approach? I recall (perhaps mistakenly) that the
> get() and put() functions were preferred to unadorned accommodate
> arrays as property maps.

The primary reason is that there is already pretty much infrastructure
to adapt function objects. Although property maps may be different
beasts, especially when it comes to the read/write categories, they
can often benefit from easy adapting, be it to change the operation
or use them e.g. with a 'reference_wrapper' to pass them along.

For me, a secondary reason is that I never really liked the free
functions: they use rather generic and short names. ... and the
entities are also better bundled using the function object style
(maybe, at the very core, I'm still devoted to object orientation for
some irrational reasons). Using function objects also allows for
using normal functions as property maps when the actual value can be
computed from the cursor's key value.

Finally, I have to admit that I haven't really done a proper analysis
of the advantages and disadvantages of each style: using function
objects just feels right. It looks right, too...
--
<mailto:dietma...@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence

Steven E. Harris

unread,
Mar 11, 2006, 8:14:04 AM3/11/06
to
David Abrahams <da...@boost-consulting.com> writes:

>> I recall (perhaps mistakenly) that the get() and put() functions
>> were preferred to unadorned accommodate arrays as property maps.
>
> I can't parse "...to unadorned accommodate arrays...," sorry.

Sorry -- sloppy editing on my part. I meant "to accommodate unadorned
arrays", meaning that an array could be a property map with an size_t
index as its key.

> I think you're referring to the fact that we can't overload
> operator() for arrays directly.

Right. Also, arrays offer up operator[] by default, making them behave
as lvalue property maps.

> I think operating directly on arrays turned out not to be so
> important; it's very easy to make a lightweight wrapper that turns a
> pointer into a property map.

I see.

In any case, I'm delighted to see movement on the property map front.

--
Steven E. Harris

Steven E. Harris

unread,
Mar 11, 2006, 8:12:53 AM3/11/06
to
Dietmar Kuehl <dietma...@yahoo.com> writes:

> For me, a secondary reason is that I never really liked the free
> functions: they use rather generic and short names.

The free functions did make for easy translation of the ideas to
languages such as Common Lisp that have no notion of member functions.

> ... and the entities are also better bundled using the function
> object style (maybe, at the very core, I'm still devoted to object
> orientation for some irrational reasons).

It's strange to see the property map idea pull back in this
direction. I associate it still with the BGL, one of the strongest
shots across the bow of OOP in favor of generic functions as the
central focus.

> Finally, I have to admit that I haven't really done a proper
> analysis of the advantages and disadvantages of each style:

I had assumed get() and put() came about in the same spirit as
std::iterator_traits -- incorporate arrays and pointers as first-class
participants, admittedly by introducing some cruft elsewhere. There's
something to admire in such a solution.

> using function objects just feels right. It looks right, too...

I'll have to give it a try.

--
Steven E. Harris

David Abrahams

unread,
Mar 20, 2006, 9:24:59 AM3/20/06
to
"Steven E. Harris" <s...@panix.com> writes:

> Dietmar Kuehl <dietma...@yahoo.com> writes:
>
>> For me, a secondary reason is that I never really liked the free
>> functions: they use rather generic and short names.
>
> The free functions did make for easy translation of the ideas to
> languages such as Common Lisp that have no notion of member functions.

It's pretty ironic that we're told function call syntax makes things
more difficult when moving to functional languages!

>> ... and the entities are also better bundled using the function
>> object style (maybe, at the very core, I'm still devoted to object
>> orientation for some irrational reasons).
>
> It's strange to see the property map idea pull back in this
> direction.

It's a pull forward :)

> I associate it still with the BGL, one of the strongest
> shots across the bow of OOP in favor of generic functions as the
> central focus.

That's true, although the idea of using function call syntax came from
a person responsible for the BGL: Doug Gregor.

>> Finally, I have to admit that I haven't really done a proper
>> analysis of the advantages and disadvantages of each style:
>
> I had assumed get() and put() came about in the same spirit as
> std::iterator_traits -- incorporate arrays and pointers as first-class
> participants, admittedly by introducing some cruft elsewhere. There's
> something to admire in such a solution.

So, now we're incorporating functions as first-class participants.

>> using function objects just feels right. It looks right, too...
>
> I'll have to give it a try.

Let us know how things work out.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

0 new messages