Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2000-07-18 09:11:41

----- Original Message -----
From: "John Maddock" <John_Maddock_at_[hidden]>

> Changed to:
> "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!)."

This is better, but you still need a period or semicolon after "array
itself", rather than a comma.

Just noticed something else in your 1st table:
"Defines a type that represents a reference to type T. Use for methods that
would normally return a T&."
Should say "functions", not "methods".

> >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?

I don't know the answer to that question.

> >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
> usage.

I'm trying to get you to clarify your language. Does the example have
anything to do with std::pair? If so, what? If not, please strike the

> >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.

Is a pointer a compound type or a fundamental type? This should cover
pointers, shouldn't it?

> >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
> implement that proposal, without the need for a language change."

Sorry, I still don't like it. They don't implement the proposal. They
provide a (tedious) workaround for the same problems that the proposed
language change would solve.

> 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
> assembler code.

I thought of two things:
1. The optimization I propose is not strictly equivalent: someone might take
the address of the parameter
2. another optimization in the same category. Can we do this with call

// use this implementation by default
template <class X>
const X& max(const X& x, const X& y) { return y < x ? x : y; }
// but this one for fundamental types
template <class X>
X max(X x, X y) { return y < x ? x : y; }

> 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[2]> then the declared template parameter is
> int[2], but the associated variable is of type int*. This can really
> 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
> 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
> a parameter.

You need an example right here. Say, "T is of type <...>, but X is of type
<...>" (or something). Show a potential problem being caused.

> 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.

Put another example here, which shows the problem being addressed.

> For value_type (return by value), again only a pointer may be returned,
> 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, gregod at, cpdaniel at, john at