Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2004-04-02 10:50:41


From: David Abrahams <dave_at_[hidden]>
> Rob Stewart <stewart_at_[hidden]> 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_at_[hidden]
Software Engineer                     http://www.sig.com
Susquehanna International Group, LLP  using std::disclaimer;

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk