gpt4 book ai didi

c++ - 元编程,试图避免许多特化

转载 作者:行者123 更新时间:2023-11-30 03:38:32 25 4
gpt4 key购买 nike

我正在为旧程序添加新内容而工作,旧程序到处都使用元编程。我仍在使用 C++ 03 和 boost。所以这是一个问题:我制作了模板函数,但我不想对其进行专门研究,因为获取特定值的四个函数调用的唯一区别是:

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

每条消息的header中都有条件变量,依赖于它 getValue()应该从消息中获取字段或返回零。如果类型没有附加,则该字段可以在消息本身中,或者在附件中,或者如果消息带有附件,则同时在消息本身。

我需要像 Base class 这样的东西来处理没有附件的消息,而 Extended 来处理有附件的消息像这样的东西:

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;

期望类模板得到..类模板!,但不知何故未被识别。

编辑:我解决了这个错误,这是因为:

Like normal (non-template) classes, class templates have an injected-class-name (clause 9). The injected-class-name can be used with or without a template-argument-list. When it is used without a template- argument-list, it is equivalent to the injected-class-name followed by the template-parameters of the class template enclosed in <>. When it is used with a template-argument-list, it refers to the specified class template specialization, which could be the current specialization or another specialization.

正确的代码:

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

关于c++ - 元编程,试图避免许多特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39516754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com