2016-09-15 50 views
1

我正在爲舊程序添加新內容,他們在任何地方都使用元編程。我仍然在c + + 03和提高。 因此,這裏是一個問題: 我做模板的功能,我不希望因爲在四個功能唯一的區別專門調用來獲得特定的值:元編程,試圖避免許多專業化

template < typename Message > 
void function(const Message & message) 
{ 
    .... 
    int value = getHelper...getValue(); 
    .... 
} 

有許多不同的信息類型:

  1. MessageA: public BaseForA<MessageA>
  2. MessageB: public BaseForB<MessageB>
  3. template < typename Appendage > MessageAWithAppendage <Appendage>: public BaseForA< MessageA <Appendage> >
  4. template < typename Appendage > MessageB: public BaseForB<MessageB>: public BaseForB< MessageB <Appendage> >

和兩個附屬物類型:
SmallAppendage
BigAppendage

有狀態變量在每個消息的標題,這取決於它 getValue()應該從消息得到外地或回零。如果類型沒有附件,則該字段可以在消息本身中,如果消息具有附件,則該消息本身可以在附件中,或者在消息本身的附件中。

我需要的東西像無附屬物消息的基類和擴展與附屬物 類似的消息:

template < typename Message > 
class Helper 
{ 
public: 
    virtual int getValue(const Message & msg) 
    { 
     if(..) 
     { 
      return msg.value; 
     } 
     ... 
    } 
}; 

template< template <class> class Message, typename Appendage > 
class ExtendedHelper : public Helper < Message <Appendage> > 
{ 
public: 
    virtual int getValue(const Message<Appendage> & msg) 
    { 
     int value = Helper::getValue(msg); 
     if(value) 
     { 
      return value; 
     } 
     return msg.appendage.getValue(); 
    } 
}; 

之後,我認爲這樣的事情會的工作,但它不是:

template < class Type > 
struct AppendageTraits 
{ 
    enum { appendageIncluded = false }; 
}; 

template < class Appendage > 
struct AppendageTraits < MessageAWithAppendage <Appendage> > 
{ 
    enum { appendageIncluded = true }; 
}; 

template < class Appendage > 
struct AppendageTraits < MessageBWithAppendage <Appendage> > 
{ 
    enum { appendageIncluded = true }; 
}; 

template< typename Message , bool > 
struct GetHelper 
{ 
    Helper<Message> * operator()() 
    { 
     static Helper<Message> helper; 
     return &helper; 
    } 
}; 

編輯:我的特質現在編譯。是否有可能使這一工作:

template < typename Appendage > 
struct GetHelper<MessageAWithAppendage <Appendage>, true> 
{ 
    Helper< MessageAWithAppendage <Appendage> > * operator()() 
    { 
     static Helper< MessageAWithAppendage <Appendage>, Appendage > helper; 
     return &helper; 
    } 
}; 

template < typename Appendage > 
struct GetHelper<MessageBWithAppendage <Appendage>, true> 
{ 
    Helper< MessageBWithAppendage <Appendage> > * operator()() 
    { 
     static ExtendedHelper< MessageBWithAppendage <Appendage>, Appendage > helper; 
     return &helper; 
    } 
}; 

編輯:現在有型/價值不匹配的參數1

static ExtendedHelper< MessageAWithAppendage <Appendage>, Appendage > helper; 

預期類模板了..類模板!但它不是以某種方式確定。

編輯: 我解決了這個錯誤,這是因爲這個:

像正常(非模板)類,類模板有一個注入的類名(第9條)。注入類名可以使用或不使用模板參數列表。在沒有template-argument-list的情況下使用它時,它相當於注入的類名,後面跟着包含在<>中的類模板的模板參數。當它與模板參數列表一起使用時,它指向指定的類模板特化,它可能是當前的特化或另一種特化。

正確的代碼:

template < typename Appendage > 
struct GetHelper<MessageAWithAppendage <Appendage>, true> 
{ 
    Helper< MessageAWithAppendage <Appendage> > * operator()() 
    { 
     static Helper< MessageAWithAppendage, Appendage > helper; 
     return &helper; 
    } 
}; 

template < typename Appendage > 
struct GetHelper<MessageBWithAppendage <Appendage>, true> 
{ 
    Helper< MessageBWithAppendage <Appendage> > * operator()() 
    { 
     static ExtendedHelper< MessageBWithAppendage, Appendage > helper; 
     return &helper; 
    } 
}; 

回答

2

我的頭在閱讀完所有,經過傷害,但如果它是唯一一個要專門操作,爲什麼不能讓與(可能是模板化)重載算符(本質一個靜態訪問者):

struct ValueGetter 
{ 
    int operator()(const MessageA& ma) const { 
    return ma.whatever_we_need_to_do(); 
    } 
    int operator()(const MessageB& mb) const { 
    return mb.whatever_we_need_to_do(); 
    } 
}; 

// this is now completely generic 
template < typename Message > 
void function(const Message & message) 
{ 
    .... 
    ValueGetter vg; 
    int value = vg(message); 
    .... 
} 
+0

我將需要4個這樣的值geters每個6專業化,這是如果我不會找到如何使它更緊湊。 – Ambrase

+0

繼續尋找共同的東西來專注於。一些成員函數本身可以是模板。他們實例化更多的獲得者。 –

+0

這就是我想要實現的。看看最新的問題,如果我會找到如何讓助手作爲我的特質工作,那麼一切都將變得緊湊。 – Ambrase