
From: David Abrahams <dave@boost-consulting.com>
Rob Stewart <stewart@sig.com> writes:
To get the ball rolling, here are my definitions. They provide clear, non-overlapping concepts, which I think are important characteristics.
Before launching into a formal definition, I should have tried to characterize my ideas better.
Trait - A class template parameterized on a single type that associates information with that type. A traits class, therefore, provides an external, named grouping of metainformation, behavior, or both for that type. A trait class is never passed as a template parameter; it's name is ubiquitous.
Whoops, can't agree there. The boost type traits are passed as template parameters all the time:
mpl::apply_if< is_pointer<X>, remove_pointer<X>, add_reference<X> >
That's not quite what I meant. To me, a traits class is the one and only supplier of that information for a given type (within a library or namespace anyway). You can make it a class template -- and would almost never choose to not do that -- and specialize it for various types, but the traits class/specializations are the sole source of that information. A traits class can provide types (typedefs and nested types), static constant values, and static mfs. IOW, if you want "character traits" as defined by the Standard Library, you use std::char_traits<T>. If you want character traits as defined by another library (or namespace), you use some other class. However, within a library, there would never be more than one class from which to choose to get character traits. mpl::apply_if wants a Boolean condition and two type choices from which to select. apply_if doesn't use any of those template parameters as a trait. It isn't doing what I was trying to describe in my definition, so my definition is faulty in this regard.
A traits class never has state.
By that I meant no non-static state. For that matter, it has no non-static members at all. I should have put *that* in my definition.
Policy - A class template passed to other templates for the purpose of providing a named grouping of metainformation,
I think a Policy might be a non-templated class.
Oops! You're right.
behavior, or both to those templates. Because it is a template parameter, different policy classes can be used as desired. In many cases, a policy class is used as a base class.
What do you think? I know that my definitions mean that std::char_traits is a policy class, despite its name, and they probably deviate from some other ad hoc definitions. The question is whether these provide sound, distinct, and defensible concepts that could be codified for future use at Boost (and elsewhere).
I think your definitions are mostly on target, but I think where you go wrong is that traits/policies has less to do with how a template is defined than how it's used.
I think that std::char_traits is actually a traits class because it is the sole provider of that information in the Standard Library and its present use within the library isn't the only way it can be used. I was thinking only about its use as a template parameter within the Standard Library. In that case, as you and others have pointed out quite rightly, it is being *used* as a policy and so it is the template parameter name that is wrong. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;