
David Abrahams writes:
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.
To me a traits class provides information to a template class that gives (possibly platform or type dependant) information. For example, the decimal point character (100.00 or 100,00?) would be in a traits class (I know this is in a locale, but this is an example). Another example would be a format string to use as a separator between items in a list, depending on whether a character, string, wide character, wide string, etc are used.
A policy class provides functional, i.e. behavioral, information. Examples include string comparison, pointer validation (for smart pointers) and error handling (e.g. smart pointers and how to handle InvalidPointer - nothing, throw std::exception, assert failure, etc.).
I disagree here. I don't think that type of the information id key thing here (and I think it's common misunderstanding). I think it's perfectly legitimate to define behaviors in trait classes in case if that behavior is uniquely identified by the type (vs. could be different for the same type). For example, one could define trait like this: template<typename T> struct my_print_function { static void print( ostream& os, T const& t ) { os << t; } } template<> struct my_print_function<char> { static void print( ostream& os, T const& t ) { os << hex << (int)t; } } template<> struct my_print_function<float> { static void print( ostream& os, float const& t ) { ... /* code that prints in a form aaa.bb always */; } } and so on. Here my_print_function is trait that defines how to print in my library values of different types. In some other designs PrintFunction may be policy. For example if I want to allow users of my library to be able to customize the way data gets printed. But my point here is that trait could be *anything* that we want to be purely type dependant. Gennadiy.