
Gennadiy Rozental wrote:
That's right. It's basic_string fault, which should've used char_traits
by
name in basic_string implementation.
I don't want to turn this into a std::string discussion, but if basic_string used char_traits by name, how would you define two different string types using char*, one with case-sensitive comparison and one without? With basic_string the way it is, it's possible; the way you're proposing, I don't see how to do it.
Look under "Numeric convertion lib comments" thread for more details, but short answer: don't. If you need case insensitive comparison use external predicate. No reason to change string type for that.
I read the thread. Here's what you wrote on 3/23/2004:
Here is how I see it. Trait is something type specific, IOW specific to type, IOW uniquely defined by type. If you could provide trait along with the type as a template parameter, that mean you could change it independently from the type, IOW you could define different value for trait still using the same type. For example if you have component C defined like:
template<typename T, typename Trait> struct C { ... };
You could instantiate it like C<MyT,TraitValue1> or C<MyT,TraitValue2>. So as you could see trait value is not uniquely defined by the type.
So what? The only thing I'm getting from this as to why traits should be "uniquely defined by the type" is because you've defined traits that way. But I don't see why traits have to be defined that way. I don't see what bad thing happens if C is defined as above.
Proper design would be to have trait stand alone class, like this:
template<typename T> struct Trait { value = ... };
template<typename T> struct C { here we are using Trait<T>::value, where we used to use Trait. };
Now if the user needs to define trait value (or change from using default value provided by most traits designs), she just need to define explicit/partial specialization for this type or types family.
Unless, as someone else pointed out, there already exists such a specialization.
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 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? 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? Bob