2009-12-08 16 views
7

Bazı kaynak kodlarını okuyarak, bir sonraki özellik tanımını buldum:Özellikleri tanımla. Özellikler blobs ve Metafunctions

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

Bu bana tuhaf geliyor. Tüm özellikleri benzersiz bir sınıfta şöyle gruplandırırdım:

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

Herhangi biriniz, ikinci yaklaşımın neden ilkinden daha kırılgan olabileceğini ya da yeni özellikler eklemek ne kadar zor olabileceğini anlayabiliyor musunuz?

cevap

5

Tek bir şablon sınıfına sahip olmak artık "özellikler blob" olarak adlandırılıyor. Meta işlevi (yani derleme zamanı işlevleri) ile iyi çalışmadığı için "Bloits blob" önerilmemektedir.

Bir meta işlevi, bir sınıf alan ve üzerinde biraz işlem gerçekleştiren bir şablondur. Bir şey gibi:

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

Ardından yaparak özelliklerin herhangi için meta işlevini çağırabilirsiniz:

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

Sen özellikleri blob sınıfı ile meta işlevi çağırmak mümkün olmaz çünkü orada Şimdi kullanmak için yazılan meta işlevi anlatmak için bir yoldur.

Meta işlevleri hakkında daha fazla bilgi edinmek isterseniz, C++ Template Metaprogramming kitabını öneririm.

+0

Meta programlama hakkında daha fazla bilgi için Boost MPL – KitsuneYMG

+0

@Samuel: Traits blob. Aradığım isim bu! Teşekkürler. Abrahams kitabını çoktan sipariş ettim. –

1

Bu bir stil meselesi. Örneğiniz muhtemelen daha fazla korunabilir, ancak ayrı tiplere sahip olmak, bağımsız olma avantajını sunar - tüm işaretçi türleri için topic_data_reader kolayca uzmanlaşabilir, ancak diğerlerini uzmanlık dışı bırakabilirsiniz. daha derine gitmek istiyorsanız

, ben varsayılan eksikliği sorgulamak istiyorum:

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

Bu yaklaşım gerekli typedefs sağlayan herhangi sınıfı otomatik nitelendirir anlamına gelir. Bu yazım hatalarını oluşturmak veya sınıfı uzmanlaştırmak için hala bir makro kullanılabilir, ancak bu muhtemelen gerekli değildir (özellikle seq_type, kullanıcı tarafından tanımlanan bir tür değil, tipik bir yazım hatası gibi).

DÜZENLEME: Daha büyük bir özellik sınıfıyla, nesneleri ayırmak, gereken örnekleme sayısını azaltmak için kullanılabilir, ancak özellik sınıfınız, birini kullanmanın muhtemelen başkalarını kullandığınız anlamına geldiği öğelere sahipse, bu hiçbir yarar sağlamaz.