|
Boost : |
From: Douglas Gregor (doug.gregor_at_[hidden])
Date: 2007-03-12 12:34:30
Hi Matt,
On Mon, 2007-03-12 at 08:18 -0800, Matt Doyle wrote:
> I watched your talk this weekend and it was really great. I was left
> with a question though; Obviously the stl is going to have to be
> re-written to take advantage of concepts but what about
> boost::typetraits? Will your proposal also bring in typetraits so we can
> have a single header that defines the more common things like IsFloat or
> IsPointer?
Type traits are already in TR1 and in the C++0x working paper, in the
header <type_traits>, so I wouldn't be proposing them as part of
concepts. That said, if you're using concepts, you will only need type
traits very rarely. Here's why...
Concepts aren't "is "or "has" checks like type-traits are. is_floating
makes sense as a type trait, because you can use it to detect whether a
type is a floating-point type, for instance. The equivalent IsFloating
concept, which says only whether a type is a floating-point type or not,
might be written as:
concept IsFloating<typename T> { }
You could then use IsFloating like a type trait (a yes or no answer),
but it wouldn't get you very far. For instance, you can't write any
interesting algorithms with it:
template<typename T>
requires IsFloating<T>
T negate(T x) { return -x; }
The compiler would reject this, because there is no negation operator.
Why? Well, we interpret the name IsFloating to mean that the type has
certain properties, including a negation operator. Traits work this way,
with the implication that the programmer knows what all of the
properties are for a given trait. Since templates aren't really
type-checked, it works (until it doesn't work; then you get the long
error messages).
The compiler can't interpret the name IsFloating, so it looks in the
concept bodies to see what properties the type should have. We don't
list any properties in the IsFloating concept, so we can do nothing with
our template type parameter T.
This is why you don't see "Is" or "Has" in a concept name... concepts
specify exactly what properties we expect a type to have. So, we might
write a Floating concept like this:
concept Floating<typename T> {
T operator-(T);
T operator+(T, T);
T operator-(T, T);
T operator*(T, T);
T operator/(T, T);
// ...
}
Every floating-point type has those properties, so they meet the
requirements of the Floating concept, and we can write our negate
algorithm:
template<typename T>
requires Floating<T>
T negate(T x) { return -x; }
The "is" in a concept is implied, really. The requires clause (it was
called the "where clause," up until two weeks ago) states what concept
requirements the template parameters need to meet. If a type does not
meet those requirements, the template can't be used. It's the same kind
of decision we make with is_* traits, but the compiler is doing the
work, not us.
To try to summarize this: the type trait is_floating says, "Is it a
floating point type?" whereas the concept Floating says, "This is what
it means to be a floating point type."
Cheers,
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk