给定一般形式的 POD 结构

struct case_0   { const char *foo;                       };
struct case_1i  { const char *foo; int v0;               };
struct case_1d  { const char *foo; double v0;            };
struct case_2ii { const char *foo; int v0;    int v1;    };
struct case_2id { const char *foo; int v0;    double v1; };
// etc

是否可以根据 v0v1 等数据成员的存在或不存在将函数重载集的(模板)成员分派(dispatch) - 理想情况下,不依赖于这些成员的特定类型 - 如果是这样,如何?具体地,给定
void
process(const case_0& c)
{
   do_stuff_with(c.foo);
}

template <typename case_1> void
process(const case_1& c)
{
   do_stuff_with(c.foo, c.v0);
}

template <typename case_2> void
process(const case_2& c)
{
   do_stuff_with(c.foo, c.v0, c.v1);
}

我希望为所有 case_* 结构选择每个重载,这些 v- 结构具有在其主体中使用的所有 v- 成员,并且——同样重要——没有任何未在其主体内使用的 ojit_code 成员。

这个程序必须是 100% 独立的,所以请不要使用 Boost。 C++11 特性没问题。

最佳答案

您需要编写一组特征,例如 has_v0has_v1(我确信已经在 SO 上多次演示过),然后使用它们来约束您的重载:

template <typename case_0,
  typename = typename std::enable_if<!has_v0<case_0>::value>::type,
  typename = typename std::enable_if<!has_v1<case_0>::value>::type
>
void
process(const case_0& c)
{
   do_stuff_with(c.foo);
}

template <typename case_1,
  typename = typename std::enable_if<has_v0<case_1>::value>::type,
  typename = typename std::enable_if<!has_v1<case_1>::value>::type
>
void
process(const case_1& c)
{
   do_stuff_with(c.foo, c.v0);
}

template <typename case_2,
  typename = typename std::enable_if<has_v0<case_2>::value>::type,
  typename = typename std::enable_if<has_v1<case_2>::value>::type
>
void
process(const case_2& c)
{
   do_stuff_with(c.foo, c.v0, c.v1);
}

您可以使用类似的东西简化约束
template<typename Cond>
  using Require = typename std::enable_if<Cond::value>::type;

例如
template <typename case_2,
  typename = Require<has_v0<case_2>>,
  typename = Require<has_v1<case_2>>
>
void
process(const case_2& c)
{
   do_stuff_with(c.foo, c.v0, c.v1);
}

关于c++ - 专门针对参数类型中 POD 结构成员存在与否的模板函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14222176/

10-11 22:42
查看更多