Search code examples
c++templatestype-traits

Type traits definition. Traits blobs & Metafunctions


Reading some source code, I have found next traits definition:

namespace dds {  
   template <typename Topic> struct topic_type_support { };
   template <typename Topic> struct topic_data_writer { };
   template <typename Topic> struct topic_data_reader { };
   template <typename Topic> struct topic_data_seq { };
}

#define REGISTER_TOPIC_TRAITS(TOPIC) \
namespace dds { \
   template<> struct topic_type_support<TOPIC> { \
      typedef TOPIC##TypeSupport type; }; \
   template<> struct topic_data_writer<TOPIC> { \
      typedef TOPIC##DataWriter type; }; \
   template<> struct topic_data_reader<TOPIC> { \
      typedef TOPIC##DataReader type; }; \
   template<> struct topic_data_seq<TOPIC> { \
      typedef TOPIC##Seq type; }; \
}

That looks weird to me. I would have grouped all the traits in a unique class like this:

namespace dds {
   template <typename Topic> struct topic_traits { };
}

#define REGISTER_TOPIC_TRAITS(TOPIC) \
namespace dds { \
   template<> struct topic_traits<TOPIC> { \
      typedef TOPIC##TypeSupport type_support; \
      typedef TOPIC##DataWriter data_writter; \
      typedef TOPIC##DataReader data_reader; \
      typedef TOPIC##Seq seq_type; \
   }; \
}  

Can any of you figure out why second approach could be more fragile than the first one or significantly harder to add new traits?


Solution

  • Having a single template class is now called a "traits blob". "Traits blob" are not recommended as they do not work well with meta-function (i.e. compile-time functions).

    A meta-function is a template that takes a class and performs some operation on it. Something like:

    template <class T>
    class metafunction
    {
        typename T::type value = ...;
    }
    

    You can then call the meta function for any of your traits by doing:

    metafunction<topic_type_support<int> >::value;
    metafunction<topic_data_writer<int> >::value;
    

    You would not be able to call the meta-function with your traits blob class because there is now way to tell the metafunction which typedef to use.

    If you want to learn more about meta-functions, I recommend the book C++ Template Metaprogramming.