|
Boost Users : |
From: Benoit Hudson (benoit.hudson_at_[hidden])
Date: 2007-06-03 14:46:07
Reading the archives, I see that the idea of adding a
template <unsigned i> T get();
function to boost::array has been somewhat summarily rejected as unnecessary:
http://lists.boost.org/boost-users/2005/08/12983.php
et seq.
And yet I'm finding myself wanting it repeatedly. Here are three
places I've seen it crop up:
(1) My current application is an arbitrary-dimensional geometry code.
I want it to be a template argument what dimension we live in (2, 3,
4, ...). In d dimensions, a simplex has d+1 vertices on it, a point
has d coordinates, and an face is a (d-1)-dimensional simplex that has
d vertices. You can imagine the potential for off-by-one bugs
(personally, I need not imagine). These get caught at runtime when
using the array operator[], but I'd rather they be caught at compile
time when possible. Therefore, when I'm feeling caffeinated, I write
the appropriate BOOST_STATIC_ASSERT (which is of course itself
sometimes off by one).
(2) I've seen (and written) rather a lot of GUI, networking, and
cross-language glue where a common idiom is to have an array of
function pointers. Sometimes, the 'name' of the function is an
integer read in at runtime. Sometimes, it is known at compile-time.
Typically I've seen this implemented using an enum; calling function i
is then functions[i](args), whereas calling function foo is
functions[FOO](args). The former one can only be checked at run-time.
The latter one should be checked at compile-time. It's fine for me to
force me to write it as functions.get<FOO>(args) to get compile-time
checking, but I do not want to be forced to change both entry FOO in
the array, and every call to foo() elsewhere, if I change the name of
the function (i.e. during debugging). When I've done this in the
past, I've been living in C-land or C++ without boost, so the idea of
compile-time checking didn't even occur to me (and, of course, bugs
cropped up all the time).
(3) Sometimes I don't need an array at all -- I just want a tuple with
all values the same type. It's far handier to declare that type as
array<foo, 4> than as tuple<foo, foo, foo, foo>. Also, we can now
also use the uber-delicious BOOST_FOREACH on the array, which can't be
done on the tuple.
Summarizing: whenever a client wants to use both integers and names to
access a field, array::get<> is useful and matches the boost
philosophy of compile-time checking over runtime checking. The change
is small in terms of LOC, and does not affect any code outside this
one function (and, as far as I can determine, is even ABI-compatible
with the prior array code). The runtime implication is nil.
-- Benoît
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net