The Role and Implementation of the Traits Classes
As used here, the traits classes define a unified interface for both the visitors and the data-batches, and adapt to the interfaces of the existing classes. As such, they are the "adapter" classes at a compile-time level.
As stated above, it is possible to re-group traits classes according to certain traits of each class. For instance, the traits class itself can be derived from a variable set of classes that is determined by the actual traits of each class. For example, if some of our data-batch classes have a visit function that takes a pointer to the visitor, rather than a reference, that could be implemented as follows:
template < typename T > struct accepts_pointer : boost::false_type {}; namespace Details { template < typename DataBatchType, typename VisitorType, typename AcceptsPointer > struct DataBatchTraits_visit { static void visit(DataBatchType * data_batch) { VisitorType visitor(VisitorTraits< VisitorType >::create()); data_batch->acceptVisitor(visitor); } }; template < typename DataBatchType, typename VisitorType > struct DataBatchTraits_visit< DataBatchType, VisitorType, boost::true_type > { static void visit(DataBatchType * data_batch) { VisitorType visitor(VisitorTraits< VisitorType >::create()); data_batch->acceptVisitor(&visitor); } }; } template < typename DataBatchType, typename VisitorType > struct DataBatchTraits : Details::DataBatchTraits_visit< DataBatchType, VisitorType, typename accepts_pointer< DataBatchType >::type > { };
in which case the meta-function accepts_pointer determines which version of DataBatchTraits_visit is used. By default, accepts_pointer "returns" false (or rather: boost::false_type), but a specialization of accepts_pointer like this:
template <> struct accepts_pointer< DataBatchType2 > : boost::true_type {};
indicating that DataBatchType2 implements an acceptVisitor function that takes a pointer to the visitor rather than a reference, would change the traits for DataBatchType2 accordingly. Hence, only one class of traits is necessary, which derives from any number of little traits classes according to any number of compile-time flags, implemented as compile-time meta-functions.