首先,代码:
template<typename Func, typename Func2>
void ForEachField(Func normalHandler, Func2 arrayHandler = NULL, bool skipUnknowns = true)
{
for(int i = 0; i < mFields.size(); ++i)
{
Field *f = mFields[i];
if(skipUnknowns && f->IsUnknown())
continue;
if(f->GetCount() == 1 || !arrayHandler)
normalHandler(f);
else
arrayHandler(f);
}
}
使用示例:
df->ForEachField(
[&](Field *field) { f << "\t" << format("public $%s;\n") % field->GetName(); },
[&](Field *field) { f << "\t" << format("public $%s;\n") % field->GetName() % field->GetSize(); }
); // Works
df->ForEachField(
[&](Field *field) { WriteLine(f, format("\t\t'%s' => array('type' => '%s'),") % field->GetName() % field->GetTypeInfo()->Name);
}); // Doesn't work
第二个电话不起作用,因为它说:
OutputPhp.cpp(27):错误C2783:'无效 数据文件:: ForEachField(FUNC键FUNC2,布尔)” :无法推断出模板参数 为'Func2' 请参阅'DataFile :: ForEachField'的声明
有没有办法让第二个参数可选,同时仍然使用模板,而不必手动指定第二个模板参数?
答案 0 :(得分:3)
您可以为ForEachField
添加重载:
template<typename Func>
void ForEachField (Func normalHandler)
{
ForEachField<Func, void *>(normalHandler, NULL, true);
}
答案 1 :(得分:1)
我知道代码重复通常被视为“坏”,但是在这种情况下,我可能不会使用运行时检查来检测我是否传递了参数...每当检查可以在编译时完成。 ..
template<typename Func, typename Func2>
void ForEachField(Func normalHandler, Func2 arrayHandler, bool skipUnknowns = true)
{
for(int i = 0; i < mFields.size(); ++i)
{
Field *f = mFields[i];
if(skipUnknowns && f->IsUnknown()) { continue; }
if(f->GetCount() == 1) { normalHandler(f); }
else { arrayHandler(f); }
}
}
template<typename Func>
void ForEachField(Func normalHandler, bool skipUnknowns = true)
{
for(int i = 0; i < mFields.size(); ++i)
{
Field *f = mFields[i];
if(skipUnknowns && f->IsUnknown()) { continue; }
if(f->GetCount() == 1) { normalHandler(f); }
}
}
请记住,您可以像往常一样完美地重载功能模板。
这将反过来解决两个问题:
operator!
的应用(不起作用)答案 2 :(得分:0)
由于您已经使用了C ++ 0x功能(lambdas),只需使用另一个:默认模板参数
template<typename Func, typename Func2 = void*>
void ForEachField(Func normalHandler, Func2 arrayHandler = NULL, bool skipUnknowns = true)
答案 3 :(得分:0)
如何使第二个参数成为非默认值,并创建一个带有单个typename Func
参数的重载包装器方法。