
On the other hand policy is something that is orthogonal to the primary type (actually in policy based design there may not be any primary type, but just an orthogonal policies), IOW you could use different policies in conjunction with the same type. And natural place for the policy is along with type in component definition among the template parameters.
You seem to be arguing that
template<typename T, typename U = traits<T> > class Foo { };
is wrong because it blurs the distinction between traits and policies. I
I think Gennadiy would agree that this is fine because U is a policy template parameter defined to use at least a subset of traits' interface.
I agree. It may even theoretically be possible that Foo uses U interface that has nothing to do with trait<T> being the trait. But! It would make me very wary. Even though I admit above is possible, in most cases it's sign of incorrect design.
If U isn't well-defined and traits becomes the definition of U, even though Foo doesn't use all of traits' interface, then the design of Foo is poor. That would seem to be the case with std::basic_string and std::char_traits. I haven't looked at the implementation with this in mind, but I'm guessing that std::basic_string doesn't use all of std::char_traits interface, and yet the "traits" parameter of std::basic_string isn't defined separately.
I am not sure where you going with "doesn't use all of std::char_traits" IMO it does not matter which part if char_traits interface basic_string is using.. In any case it should've referred to it by name and not through template parameter.
say "so what?" If the problem is best solved by blurring these ideas, blur away. No one seems to have yet been able to define "traits" and "policies" very well anyway, so what are we blurring?
*If* there is value, as I of course think there is, in maintaining a distinction for accuracy in discourse, then we're needlessly combining separate notions. If few think the distinction is important, then we should simply choose one or the other term to avoid confusion.
On 1/3/2004, you wrote
I've expressed my opinion in the matter before: Traits - as name suggest could not be policy. IOW should not be template parameters. Traits are type specific and an ability to supply them independently to the primary type in most cases leads to invalid/too complicated design.
The way I read this, your use of "most cases" means you agree there are some cases where the above use of traits passed into a template is justified and acceptable. This seems to contradict the idea above that traits can never be used this way. Can you clarify please?
If an existing traits class provides (at least) the interface needed for a template's policy class, then using the traits class as that policy should be fine. The fact that the template parameter is a policy means that the template is allowing for other implementations of that interface. That doesn't make the traits class any less the one definition of those traits. Put another way, any other classes implemented to be used as the template's policy argument won't be used as traits; they'll only be used as the template's arguments.
The distinction provides some clarity when using the phrases "traits class" or "policy class." When someone says "policy class," you immediately know that they mean something passed as a template argument or the template parameter used within the template to effect behavioral changes. When someone says "traits class," you immediately know that they mean something customizable for each distinct type, but not for each template wishing to use it. Those are quite different things and disambiguiating them via different names is sensible.
Very true. Gennadiy.