我正致力于为旧程序添加新内容,旧程序在任何地方都使用元编程。我仍然在c ++ 03和提升。 所以这是一个问题: 我做了模板功能,我不想专门化,因为只有四个函数调用的差异才能得到特定的值:
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 > >
两种附肢类型:
SmallAppendage
BigAppendage
每条消息的标题中都有条件变量,具体取决于它
getValue()
应该从消息中获取字段或返回零。如果类型没有附属物,则该字段可以在消息本身中,
或者在附件中,或者如果消息附带附件,则同时在消息本身。
对于没有附属物的消息,我需要类似Base类的东西;对于带有附属物的消息,我需要扩展 类似的东西:
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节)。 inject-name-name可以使用或不使用template-argument-list。如果在没有template-argument-list的情况下使用它,它等同于inject-name-name,后跟&lt;&gt;中包含的类模板的template-parameters。当它与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;
}
};
答案 0 :(得分: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);
....
}