2016-09-15 35 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