
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