给定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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。