类型特征定义。特质blob&元函数

时间:2009-12-08 23:30:18

标签: c++ templates typetraits

阅读一些源代码,我找到了下一个特征定义:

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; }; \
}

这对我来说很奇怪。我会将所有特征分组在一个独特的类中,如下所示:

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; \
   }; \
}  

你们中任何一个人都能弄清楚为什么第二种方法比第一种方法更脆弱或者更难以添加新特性?

2 个答案:

答案 0 :(得分:5)

拥有单个模板类现在称为“traits blob”。不建议使用“Traits blob”,因为它们与元函数(即编译时函数)不兼容。

元函数是一个模板,它接受一个类并对其执行一些操作。类似的东西:

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

然后,您可以通过执行以下操作调用任何特征的元函数:

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

您将无法使用特征blob类调用元函数,因为现在可以告诉元函数使用哪个typedef。

如果您想了解有关元功能的更多信息,我建议您使用本书C++ Template Metaprogramming

答案 1 :(得分:1)

这是一种风格问题。您的示例可能更易于维护,但是具有单独的类型确实赋予了它们独立的优势 - 您可以轻松地对所有指针类型进行专门化,例如topic_data_reader,但保留其他类型的非专业化。

如果你想更深入,我会质疑缺乏默认值:

namespace dds {
  template <typename Topic> struct topic_traits {
    typedef typename Topic::type_support type_support;
    typedef typename Topic::data_writer data_writer;
    typedef typename Topic::data_reader data_reader;
    typedef typename Topic::seq_type seq_type;
  };
}

这种方法意味着任何提供必需typedef的类都会自动获得资格。宏仍然可以用于生成那些typedef或者专门化类,但这可能不是必需的(seq_type看起来很可疑,因为它通常是typedef,而不是用户定义的类型。)

编辑:使用更大的特征类,可以使用分离的东西来减少所需的实例化数量,但是如果你的特征类具有使用一个元素的元素可能意味着你正在使用其他元素,这就没有任何好处。 / p>