代码之家  ›  专栏  ›  技术社区  ›  Fernando N.

类型特征定义。特征块和元函数

  •  7
  • Fernando N.  · 技术社区  · 15 年前

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

    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 回复  |  直到 15 年前
        1
  •  5
  •   R Samuel Klatchko    15 年前

    拥有一个模板类现在称为“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;
    

    您将无法使用traits blob类调用元函数,因为现在有方法告诉元函数要使用哪个typedef。

    如果你想了解更多关于元函数的知识,我推荐这本书 C++ Template Metaprogramming .

        2
  •  1
  •   coppro    15 年前

    这是风格问题。您的示例可能更易于维护,但是拥有单独的类型确实会带来独立的优势—您可以很容易地专门化,比如, 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,而不是用户定义的类型)。

    编辑:有了一个更大的traits类,分离东西可以用来减少所需的实例化次数,但是如果traits类有一些元素,其中使用一个可能意味着使用其他的,那么这就没有任何好处。