From: John Maddock (John_Maddock_at_[hidden])
Date: 2000-07-18 06:06:05
Thanks for looking at that I appreciate the feedback,
>It might be clearer if you swapped the two sentences above.<
>In the first table, why does note 1 appear with
>Regardless of partial-specialisation, you can always return T and avoid
>references-to-references. It seems like "(requires partial
>is meaningless in this particular case. Also, I have nothing against the
British spelling, but
>the standard defines the term with a 'z', so it's more precise (I think)
to use the same
>spelling. I think the standard also writes "copy-constructible" where you
> a.. If T is an array type, then call_traits defines value_type as a
"pointer to type"
>rather than an "array of type" (requires partial specialisation). Note
that arrays can
>not normally be copied so instead this will result in storing a "pointer
to an array"
>rather than the array itself, this may or may not be a good thing
depending upon the
>usage of the class in question (in other words take care!).
>I think the word "storing" is misleading here; it would be better if you
just removed it.
>The comma after "itself" should be a period. What "class in question?"
>you should just say "depending on your needs".
"If T is an array type, then call_traits defines value_type as a "constant
pointer to type" rather than an "array of type" (requires partial
specialization). Note that if you are using value_type as a stored value
then this will result in storing a "constant pointer to an array" rather
than the array itself, this may or may not be a good thing depending upon
what you actually need (in other words take care!)."
> If T is a small built in type or a pointer, then param_type is defined
as T const, instead of T const&.
>This can improve the ability of the compiler to optimise loops in
>the body of the function if they depend upon the passed parameter, the
>the passed parameter is otherwise unchanged (requires partial
>This doesn't agree with the 3rd table which says that param_type<int> is
just plain int (not "int const").
>Also, it would help if you were consistent about the placement
>of const. In other places you write "const int".
const int is correct, that was a typo in the table, thanks - in fact I
notice a few more const-inconsistancies which have been tidied up.
>I think you want to say "...are true if and only if T is..."
> If T is an assignable type the following types are assignments are
>"are" should be "of"
Yep, woolly English again...
>I think if there's no partial-specialization you can still use
call_traits::value_type with reference types. <
Probably, I just can't think of any useful pattern of usage that would use
value_type without also using the others - actually is it legal C++ to
instantiate a template that contains illegal typedefs, if those typedefs
are not used?
>What does "is a model for std::pair" mean? This example does not have
enough (correct?) motivating commentary to make it useful.<
It's more of a test case, and illustration, just to introduce call_traits
>No apostrophe in the possessive form of "its".<
Yep that always catches me out....
>Add "and one that works safely even in generic code where the cast might
do the wrong thing"<
>I'm all for out-of-class function bodies, but I think in this case it just
harms readability of the example.<
Yep, that's what comes of cutting and pasting code :-)
>I think the word you want here is "rationale".
I think you're correct.
>I guess you should say "small built-in non-reference types". An int& is a
small built-in type, right?
No, a reference is a compound type, I should have said "fundamental type"
though to be precise.
>I wouldn't say "mirrors". You might want to try to find a better word.
Also, why is call_traits<const int&>::param_type
> "const int&" and not simply "const int"? Wouldn't
>that be more efficient and probably otherwise equivalent?
How about "There is a proposal to modify the language such that "a
reference to a reference is a reference" (issue #106, submitted by Bjarne
Stroustrup), call_traits<T>::value_type and call_traits<T>::param_type both
implement that proposal, without the need for a language change."
I see what you mean about the "const T&" case - it would require another
partial specialisation (I think) - does anyone have any strong opinions on
this - note that the "efficiency gains" are pretty small - often
unmeasurably so, even when the compiler is definately producing better
>Need a period, semicolon or colon after "degrade the array type to a
>I'm not sure what "makes the conversion explicit" means in this context.
Is that an advantage?
>Maybe what you're trying to say is "forces that degrading to happen where
it might not otherwise,
>in cases of deduced template type parameters"?
Umm this is a tough one to rationalise: I think the problem is that when
the compiler degrades the type of the passed parameter, the declared
parameter type is a different type from variable it declares:
template <class T> void foo(T t);
If you now instantiate foo<int> then the declared template parameter is
int, but the associated variable is of type int*. This can really screw
up template code that relies on a deduced type. To be honest, the array
specialisation is the least understood of all the call_traits
specialisations, it's never been very clear what the ideal semantics should
be, the ones chosen are a compromise that work in a few important test
cases, but we really need more real world usage examples to tie this down,
it's one of those annoying "corner cases".
I've rewriiten this to:
"For array types, a function that takes an array as an argument will
degrade the array type to a pointer type: this means that the type of the
actual parameter is different from its declared type, something that can
cause endless problems in template code that relies on the declared type of
a parameter. By using call_traits the degradation from array to pointer is
explicit, and the type of the paramter is the same as it's declared type.
For value_type (return by value), again only a pointer may be returned, not
a copy of the whole array, and again call_traits makes the degradation
explicit. The value_type member is useful whenever an array must be
explicitly degraded to a pointer - Example 3 provides the test case
(Footnote: the array specialisation for call_traits is the least well
understood of all the call_traits specialisations, if the given semantics
cause specific problems for you, or don't solve a particular array-related
problem, then I would be interested to hear about it. Most people though
will probably never need to use this specialisation)."
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk