其他分享
首页 > 其他分享> > c – 在参数类型中存在或不存在POD结构成员时专门化模板函数

c – 在参数类型中存在或不存在POD结构成员时专门化模板函数

作者:互联网

给定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

是否可以根据v0,v1等数据成员的存在与否来调度(模板)函数重载集的成员 – 理想情况下,不依赖于这些成员的特定类型 – 如果是,怎么样?具体地说,给定

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成员.

这个程序必须是100%自包含的,所以请不要提升. C 11功能还可以.

解决方法:

您需要编写一组特征,例如has_v0和has_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,c11,templates,sfinae
来源: https://codeday.me/bug/20190901/1782754.html