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