|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2002-10-19 23:01:52
Just reading through the Signals docs here, and came across a strange
use of the term "named template parameter":
boost::signal<float (float x, float y),
maximum<float> > sig;
This is supposed to be a use of named template parameters to pass
maximim<float> to the signal class. Where's the "named parameter?"
This doesn't look anything like NTP as we've seen, e.g., in the
iterator adaptors library.
-- Also, I was wondering about the iterators which get passed to combiners. I can imagine two ways this could work: 1. The signal builds a sequence of return values, and then passes iterators to the sequence into the combiner. 2. The signal builds iterators which invoke the slots lazily. The upshot is that the if the combiner stops looking at the sequence partway through, only a subset of the slots get called. The tutorial docs don't mention which model gets used. Ah, if I dig into the reference docs I can see that it's the 2nd model. Well, I think the tutorial should mention this. -- Also, various of the Signals doc pages incorrectly use the word "Rational" where "Rationale" should appear. -- Also also, the description of "preferred" and "compatible" syntaxes fails to make it clear that the compatibile syntax works on all of the compilers listed. I think it's important that people who want to write portable code don't think they have to litter their code with #ifdefs just to use this library. -- It also says "At this time there is a significant limitation to the use of trackable objects in making slot connections: function objects built using Boost.Bind are understood, so that any place a trackable object appears in a bind expression." Isn't there a conclusion missing from this sentence? And I think you should be careful about exactly what you write. I think there are lots of ways a trackable object can "appear in a bind expression" yet still be effectively hidden from bind, e.g.: bind(bind1st(f, x), y) And what about references to trackable objects? If I build a bind expression around ref(x), will it still be tracked? -- In the section on "Passing Slots" it says "any valid function object can be passed to a slot_type parameter". Do you mean "any _compatible_ function object", using the definition of compatible from the function library? Also, the example ought to demonstrate some valid/compatible function object being passed to a slot_type parameter. -- The formal docs for disconnect read: "Complexity: O(lg n) + k where n is the number of slots known to the signal and k is the number of ." ^ I think something is missing here---+ -- The "Signal Invocation" docs say: "Effects: invokes the combiner with a slot_call_iterator range [first, last) (i.e., combiner(first, last)) that iterates over the results of calling each slot with the given set of parameters a1, a2, ..., aN." An iterator range doesn't iterate. Maybe you should say "...whose values are the results of calling..." You should also mention that if the iterator stops early, only a subset of the slots will be called. Also you should specify whether it's incrementing or dereferencing of the iterator which causes a slot call. Finally, the number of crazy font changes in this passage make it hard to read. Maybe it'd work better if all of this material were not italicized. Italics don't add much when used in bulk. In fact, it looks like this problem is due to a missing </i> tag in the previous section with the missing text. -- The formal documentation for trackable really needs to make it clear that special knowledge is required in the binder used and that only Boost.Bind currently has that knowledge. -- the docs for last_value<T> and its void specialization are confusing, since we list two identical member function declarations with different semantics. We should do something to mark the second one as the void specialization. -- The docs don't make it clear that visit_each is being called without qualification, nor do they say which boost functions call it. Both of those features are important for any point-of-customization that may use Koenig lookup. Also, I realize that with existing compilers, we have to rely on overloading in the user's namespace for this function, but some consideration ought to be given to whether a partially-specializable static member function wrapper wouldn't be the better long-term solution for this case. -- In the design document we mention Type erasure. I misread that about ten times as describing a type called Erasure. I think starting the first sentence of that section with "Type erasure" in quotes would help a lot. We also refer to "slot names", which confused me. I think we really mean "slot group names" here, since individual slots aren't named. I'd actually prefer if "name" was replaced with "identifier" or "id" throughout the docs, since "name" really suggests a string. -- rationale: "but in this case the original specification ties the implementation to the use of virtual functions internally." This is unclear. Instead of saying "in this case the original specification..." why don't we say "this arrangement still..."? And something should be said about why it's a bad thing to tie the implementation to the use of virtual functions. Most people don't think twice about using virtual functions, and are never sorry about it. "uses a set of well-defined interfaces to discover information about the composition of arbitrary function objects." Well, let's not oversell it. We can't really do that for arbitrary function objects unless visit_each has been suitably defined, can we? And, while I'm able to imagine the relationship this statement might have to the rest of the paragraph, it's not very clear. We should spell out that using primitives makes it easy for the library to track lifetimes of function object elements. The last sentence in the "pass slot to disconnect" section is a major run-on. I'm having trouble figuring out what it's supposed to mean. "This type of interface is supported in Boost.Signals via the named connections mechanism" As they say in the movies, "What the...?" Is this mechanism documented anywhere? "The "push" model, on the other hand, relies on an interface specific to the caller and is generally reusable." "not"?--------------------------^ "the connection syntax supplied by Boost.Signals is no less powerful that than supplied by the signal." What signal? -- Must trackable be a public base, or is a private base OK? Can we have an example of its use? OK, there's one in CVS. How about some links from the docs to these examples? -- I'm still wondering, after reading the docs, whether it's OK to send a signal which ultimately destroys the signal itself. -- This line in libs/signal/example/first_positive.hpp seems to rely on unspecified behavior to match its comment, since none of the slots are members of a named group. assert(sig_positive(3, -5) == 8); // returns 8, but prints nothing -- David Abrahams dave_at_[hidden] * http://www.boost-consulting.com -- David Abrahams dave_at_[hidden] * http://www.boost-consulting.com Building C/C++ Extensions for Python: Dec 9-11, Austin, TX http://www.enthought.com/training/building_extensions.html
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk