我正在努力为旧程序添加新内容,旧程序在各处都使用元编程。我仍在使用c++ 03和boost。
所以这是一个问题:
我做了模板函数,我不想专门研究它,因为仅在获取特定值的四个函数调用中存在差异:

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

有许多不同的消息类型:
  • MessageA: public BaseForA< MessageA >
  • MessageB: public BaseForB< MessageB >
  • template < typename Appendage >MessageAWithAppendage < Appendage >: public BaseForA< MessageA < Appendage > >
  • template < typename Appendage >MessageB: public BaseForB< MessageB >: public BaseForB< MessageB < Appendage > >

  • 还有两种附录类型:SmallAppendageBigAppendage
    每个消息的标题中都有条件变量,具体取决于它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;
    

    本来希望有一个类模板。类模板!,但由于某种原因无法识别。

    编辑:
    我解决了此错误,原因是这样的:



    正确的代码:
    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;
        }
    };
    

    最佳答案

    阅读完所有内容后,我的头很痛,但如果这只是您要专门研究的一项操作,为什么不使用(可能是模板化的)超载(通常是静态访问者)来创建函子:

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

    07-26 01:46