I think you will find the best answer to your question in this book by Andrei Alexandrescu . Here I will try to give a brief overview. Hope this helps.
A feature class is a class that is typically designed for a meta function that associates types with other types or with constant values ββto provide a characterization of these types. In other words, this is a way to model type properties. A mechanism typically uses templates and specialized specialization to define an association:
template<typename T> struct my_trait { typedef T& reference_type; static const bool isReference = false;
The meta my_trait<> attribute my_trait<> above associates the reference type T& and the constant Boolean value false to all types T that are not links themselves; on the other hand, it binds the reference type T& and the constant Boolean value true to all types T that are references.
So for example:
int -> reference_type = int& isReference = false int& -> reference_type = int& isReference = true
In the code, we could state the following: (all four lines below will be compiled, which means that the condition expressed in the first argument of static_assert() is satisfied):
static_assert(!(my_trait<int>::isReference), "Error!"); static_assert( my_trait<int&>::isReference, "Error!"); static_assert( std::is_same<typename my_trait<int>::reference_type, int&>::value, "Error!" ); static_assert( std::is_same<typename my_trait<int&>::reference_type, int&>::value, "Err!" );
Here you can see that I used the standard std::is_same<> template, which itself is a meta function that takes two, not one type argument. Everything can be complicated here.
Although std::is_same<> is part of the type_traits header, some consider a class template as a class of type attributes only if it acts as a meta predicate (thus, accepting one template parameter). However, to my knowledge, the terminology is not clearly defined.
For an example of using a feature class in a C ++ standard library, consider how to create an I / O library and a string library.
A policy is something a little different (in fact, quite another). Usually this is a class that indicates that the behavior of another generic class should be associated with certain operations that could potentially be implemented in several ways (and the implementation of which, therefore, is left to the policy class).
For example, a generic class of smart pointers can be designed as a template class that accepts a policy as a template parameter for deciding how to handle reference counting - this is just a hypothetical, overly simplified and illustrative example, so please try to distract from this specific code and focus on the mechanism.
This would allow the developer of the smart pointer not to make a hard-coded obligation as to whether changes to the reference counter should be performed in a thread-safe manner:
template<typename T, typename P> class smart_ptr : protected P { public:
In a multi-threaded context, the client can use an instance of the smart pointer template with a policy that implements thread-safe increments and reductions in the reference counter (it is assumed that the Windows platform is assumed here):
class mt_refcount_policy { protected: add_ref(int* refcount) { ::InterlockedIncrement(refcount); } release(int* refcount) { ::InterlockedDecrement(refcount); } }; template<typename T> using my_smart_ptr = smart_ptr<T, mt_refcount_policy>;
In a single-threaded environment, on the other hand, the client can instantiate a smart pointer template with a policy class that simply increments and decrements the counter value:
class st_refcount_policy { protected: add_ref(int* refcount) { (*refcount)++; } release(int* refcount) { (*refcount)--; } }; template<typename T> using my_smart_ptr = smart_ptr<T, st_refcount_policy>;
Thus, the library developer has provided a flexible solution that can offer the best compromise between performance and security ("You do not pay for what you do not use").