RE: [boost] Re: Policy or Trait?

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> >
What he meant, I think, is "never passed as a template parameter together with primary type"
A traits class never has state.
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.
True.
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.
Could you please rephrase. It's a bit unclear. Gennadiy.

"Rozental, Gennadiy" <gennadiy.rozental@thomson.com> writes:
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> >
What he meant, I think, is "never passed as a template parameter together with primary type"
I don't know what "primary type" means here.
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.
Could you please rephrase. It's a bit unclear.
Technically one can never say "class template foo is a traits template" or "class template foo is a policy" without examining how it's used. There's no fundamental reason that the same class template can't be used in both ways, so for any given class template, there may be no either/or answer. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:uzn9vnwtz.fsf@boost-consulting.com...
"Rozental, Gennadiy" <gennadiy.rozental@thomson.com> writes:
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> >
What he meant, I think, is "never passed as a template parameter together with primary type"
I don't know what "primary type" means here.
X in example above. Actually you may say that even my rephrasing isn't correct. One could always says mpl::apply_if<is_pointer<X>, X, "something else" > Let me try this way: For any type "T" listed in template definition no class that specify trait of the type "T" is used in a same template parameter list.
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.
Could you please rephrase. It's a bit unclear.
Technically one can never say "class template foo is a traits template" or "class template foo is a policy" without examining how it's used. There's no fundamental reason that the same class template can't be used in both ways, so for any given class template, there may be no either/or answer.
Well, technically you maybe right, though it's quite difficult to imagine an example of that. But still trait is entity that *define* compile time mapping of type to some kind of value, which maybe numaric value, another type or any other more complex thing (including something that may defines behavior). You may use it as a template parameter (not quite as a policy though in majority of the cases). Like in example above. Here we are using type trait as a selector. But is_pointer is still a trait class. Would you advokate a design that supply is_pointer along with type it applied to as a template parameters? template<typename T, typename TIsPointer> struct my_container {...}; template<typename T> struct C { my_container<T,is_pointer<T> > storage; }; So, could we say that is_pointer defines a trait? Regards, Gennadiy.

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
Well, technically you maybe right, though it's quite difficult to imagine an example of that.
char_traits is one.
But If I understood you correctly in some other place you say that char_traits is an example of bad design. And I think the same. IMO any example of trait/policy mixure in the same class would be an example of bad design. Gennadiy.

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
Well, technically you maybe right, though it's quite difficult to imagine an example of that.
char_traits is one.
But If I understood you correctly in some other place you say that char_traits is an example of bad design.
Yes. That doesn't change the fact that it acts in both ways.
And I think the same. IMO any example of trait/policy mixure in the same class would be an example of bad design.
I don't know; it seems to me that the template <class T, class Policy = xxx_traits<T> > class Foo; idiom might not be a bad one for some uses if xxx_traits is only supplying associated types. It allows customization of the meaning of Foo<X> for any X by specializing xxx_traits<X>, while also allowing users to explicitly choose Foo<X, Y> when they don't like the default for X. -- Dave Abrahams Boost Consulting www.boost-consulting.com

And I think the same. IMO any example of trait/policy mixure in the same class would be an example of bad design.
I don't know; it seems to me that the
template <class T, class Policy = xxx_traits<T> > class Foo;
idiom might not be a bad one for some uses if xxx_traits is only supplying associated types. It allows customization of the meaning of Foo<X> for any X by specializing xxx_traits<X>, while also allowing users to explicitly choose Foo<X, Y> when they don't like the default for X.
And you get basic_string design as a result. If user do not like default value for the trait. It's value should be set *externally* to the component definition. That is the major point I am trying to prove in regards to numeric_cast design and in thic generic discussion. Gennadiy.

From: "Gennadiy Rozental" <gennadiy.rozental@thomson.com>
I don't know; it seems to me that the
template <class T, class Policy = xxx_traits<T> > class Foo;
idiom might not be a bad one for some uses if xxx_traits is only supplying associated types. It allows customization of the meaning of Foo<X> for any X by specializing xxx_traits<X>, while also allowing users to explicitly choose Foo<X, Y> when they don't like the default for X.
And you get basic_string design as a result.
Sure.
If user do not like default value for the trait. It's value should be set *externally* to the component definition. That is the major point I am trying to prove in regards to numeric_cast design and in thic generic discussion.
But what about the distinction that xxx_traits<T>, a class, is being used as the Policy type in Foo? From Foo's perspective, it has a Policy which its clients can define any way they like within the constraints of what's expected of the policy. By the same token, other code, even code within Foo can use xxx_traits<T> to get information. (Foo could do it regardless of the type corresponding to the template argument Policy.) -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

If user do not like default value for the trait. It's value should be set *externally* to the component definition. That is the major point I am trying to prove in regards to numeric_cast design and in thic generic discussion.
But what about the distinction that xxx_traits<T>, a class, is being used as the Policy type in Foo? From Foo's perspective, it has a Policy which its clients can define any way they like
They sure could. Note though that this is not how basic_string is designed. There Traits parameter used as trait collection. I am yet to see an example of good design that rely on possibility of trait class to be used sometimes as policy. I still couldn't find a reason to use policy parameter that could be instantiated with trait value. It should be something that is not unique to the type but sometimes it may coinside with some other [un]related type trait. I guess it's possible. But it rare case that could be omitted in basic definition and mentioned only in "special cases" clause.
within the constraints of what's expected of the policy. By the same token, other code, even code within Foo can use xxx_traits<T> to get information. (Foo could do it regardless of the type corresponding to the template argument Policy.)
-- Rob Stewart stewart@sig.com
Gennadiy.

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
And I think the same. IMO any example of trait/policy mixure in the same class would be an example of bad design.
I don't know; it seems to me that the
template <class T, class Policy = xxx_traits<T> > class Foo;
idiom might not be a bad one for some uses if xxx_traits is only supplying associated types. It allows customization of the meaning of Foo<X> for any X by specializing xxx_traits<X>, while also allowing users to explicitly choose Foo<X, Y> when they don't like the default for X.
And you get basic_string design as a result.
My problems with basic_string arise from other choices.
If user do not like default value for the trait.
It's not a default value of a trait. It's the default value of the Policy. The default value of xxx_traits<T>::whatever is given by the primary xxx_traits template.
It's value should be set *externally* to the component definition.
Why?
That is the major point I am trying to prove in regards to numeric_cast design and in thic generic discussion.
I don't know enough about how this relates to numeric_cast to comment. -- Dave Abrahams Boost Consulting www.boost-consulting.com

From: David Abrahams <dave@boost-consulting.com>
I don't know; it seems to me that the
template <class T, class Policy = xxx_traits<T> > class Foo;
idiom might not be a bad one for some uses if xxx_traits is only supplying associated types. It allows customization of the meaning of Foo<X> for any X by specializing xxx_traits<X>, while also allowing users to explicitly choose Foo<X, Y> when they don't like the default for X.
Right. The only problem arises when xxx_traits is used as the exemplar for the policy and not all of xxx_traits' interface is needed. That can be solved with documentation, but the tendency is likely to be to copy xxx_traits and modify its functionality when creating a new policy class. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

From: David Abrahams <dave@boost-consulting.com>
Technically one can never say "class template foo is a traits template" or "class template foo is a policy" without examining how it's used. There's no fundamental reason that the same class template can't be used in both ways, so for any given class template, there may be no either/or answer.
I don't quite agree. A policy class is only that because it is a template parameter. Whether a class that is passed as a policy to some template happens to be a traits class is immaterial. So, in the context of the template, the template parameter is a policy class and that may correspond to a traits class in a particular specialization, but that doesn't make the traits class a policy class. Does that make sense? -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart <stewart@sig.com> writes:
From: David Abrahams <dave@boost-consulting.com>
Technically one can never say "class template foo is a traits template" or "class template foo is a policy" without examining how it's used. There's no fundamental reason that the same class template can't be used in both ways, so for any given class template, there may be no either/or answer.
I don't quite agree. A policy class is only that because it is a template parameter.
A class is never a template parameter. It can be a template argument.
Whether a class that is passed as a policy to some template happens to be a traits class is immaterial. So, in the context of the template, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exactly. How it's used.
the template parameter is a policy class and that may correspond to a traits class in a particular specialization, but that doesn't make the traits class a policy class. Does that make sense?
Not much, to me. I think you're trying to say the same thing I said, but in a more contorted way. -- Dave Abrahams Boost Consulting www.boost-consulting.com

I'm probably oversimplifying, but my impression is that a trait is a metafunction that provides information about a class or type. This is based on my impressions of "iterator_traits"; I know nothing about "char_traits". On the other hand, a policy class may or may not be a template and injects new types or behavior into a class. It can do this either as a template argument or by inheritance. If only we could just keep it that simple.

From: David Abrahams <dave@boost-consulting.com>
Rob Stewart <stewart@sig.com> writes:
From: David Abrahams <dave@boost-consulting.com>
Technically one can never say "class template foo is a traits template" or "class template foo is a policy" without examining how it's used. There's no fundamental reason that the same class template can't be used in both ways, so for any given class template, there may be no either/or answer.
I don't quite agree. A policy class is only that because it is a template parameter.
A class is never a template parameter. It can be a template argument.
Those two are often used interchangeably. The standard always, may use "parameter" and "argument" in those senses, but they aren't defined and common usage gets in the way. Anyway, I meant "parameter" according to that dichotomy.
Whether a class that is passed as a policy to some template happens to be a traits class is immaterial. So, in the context of the template, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exactly. How it's used.
A traits class can be used as a policy. We're agreed. However, that traits class is not a policy class. A class (template) can be created to be a policy or it can be created to be a traits class. In the former case, it is created specifically to meet a need for a policy; there is no intention that code would ever be written using its name directly. That is, it is only ever passed as a template _argument_. By contrast, a traits class is not created to be used as a policy. If a template comes along that decides the traits class' interface is appropriate to be its policy, then the traits class can be used as that templates policy. That doesn't make the traits class a policy class, IMO. Its use within the template is as a policy.
the template parameter is a policy class and that may correspond to a traits class in a particular specialization, but that doesn't make the traits class a policy class. Does that make sense?
Not much, to me. I think you're trying to say the same thing I said, but in a more contorted way.
Therein lies the rub. You _think_ we're saying the same, but neither of us is entirely sure yet. BTW, once there's agreement, we need to try our hand at definitions. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

"Rob Stewart" <stewart@sig.com> wrote in message news:200404021605.i32G5w922641@entwistle.systems.susq.com...
From: David Abrahams <dave@boost-consulting.com>
Technically one can never say "class template foo is a traits template" or "class template foo is a policy" without examining how it's used. There's no fundamental reason that the same class template can't be used in both ways, so for any given class template, there may be no either/or answer.
I don't quite agree. A policy class is only that because it is a template parameter. Whether a class that is passed as a policy to some template happens to be a traits class is immaterial. So, in the context of the template, the template parameter is a policy class and that may correspond to a traits class in a particular specialization, but that doesn't make the traits class a policy class. Does that make sense?
Ah, and here I think is the sticking point. I think we are thinking of traits and policies as complements/duals of each other. That is certainly a natural way for brains to dichotomize things. But, after writing my definitions and seeing more discussion, I am led to the conclusion that traits and policies are fundamentally different things. That is, I claim that "traitness" is a property of a *type*, but "policyness" is a property of a *usage of a type*. Thus, if a type is a metafunction that is specialized for various inputs, then it is a trait. But any type that provides configuration type data or behavior to a client metafunction is a policy. What that means is that "traitness" is a meta-static property, and "policyness" is a meta-dynamic property. That is, you can always say: "type X is a trait" or "type X is not a trait", without any context. But you can only say "type X is being used as a policy in context Y" or the inverse. Is char_traits<> a trait? Yes. Is it a policy? Depends. Is allow_conversion<> a policy? The only sensible way it is used, it is. Is it a trait? No, because it is not even a metafunction, let alone customized for its inputs. So here are my "complete" definitions of "trait" and "policy": 1. A trait T is a metafunction of the client type X such that T is customized over various X. 2. A client type X is a metafunction of a policy P such that X is customized over various P. Stated that way, I guess I'm going to contradict myself and say that they are duals of each other in some sense. Rob makes the observation that traits are usually global, while policies are usually local. I think that is nicely implied by my definitions above. A corollary is that T is a locus of customization. That is, you collect the implementation variations within specializations of T. With policies, the client type X is the locus of customization, and the specializations are spread out over the space of Ps. So really, traits and policies trade off whether you place the customization within one type, or spread it out over many types. And, of course, they may interact and overlap for those curious "traits policies" (or is that "policy traits"? ;). Note that I make no distinction about whether T does or does not include behavior (nor for P). I think that's a red herring. Dave --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.581 / Virus Database: 368 - Release Date: 2/9/2004

"David B. Held" <dheld@codelogicconsulting.com> writes:
Ah, and here I think is the sticking point. I think we are thinking of traits and policies as complements/duals of each other. That is certainly a natural way for brains to dichotomize things. But, after writing my definitions and seeing more discussion, I am led to the conclusion that traits and policies are fundamentally different things.
That is, I claim that "traitness" is a property of a *type*, but
std::iterator_traits is not a type. Don't you mean a *class template*? -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:uk70ygnd0.fsf@boost-consulting.com...
"David B. Held" <dheld@codelogicconsulting.com> writes:
[...] That is, I claim that "traitness" is a property of a *type*, but
std::iterator_traits is not a type. Don't you mean a *class template*?
Actually, I meant a metatype, so yes. But really, I was thinking of "type" not as "C++ type" but as "type or metatype or metametatype or...". I don't know if a word has been invented for that concept yet. Dave --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.581 / Virus Database: 368 - Release Date: 2/9/2004
participants (6)
-
David Abrahams
-
David B. Held
-
Deane Yang
-
Gennadiy Rozental
-
Rob Stewart
-
Rozental, Gennadiy