如何处理可选参数的模板类型名?
首先,代码:
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: 'void DataFile::ForEachField(Func,Func2,bool)' : 无法推断出模板参数 对于“功能2” 请参阅“DataFile::ForEachField”的声明
有什么方法可以使第二个参数可选,同时仍然使用模板,并且不必手动指定第二个模板参数?
First of all, the code:
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);
}
}
And an example of usage:
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
The second call doesn't work because it says:
OutputPhp.cpp(27): error C2783: 'void
DataFile::ForEachField(Func,Func2,bool)'
: could not deduce template argument
for 'Func2'
see declaration of 'DataFile::ForEachField'
Is there any way I can make the second parameter optional, while still using templates, and while not having to manually specify the second template argument?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以为
ForEachField
添加重载:You could add an overload for
ForEachField
:我知道代码重复通常被认为是“坏”的,但是在这种情况下,我可能不会使用运行时检查来检测我是否传递了参数...只要可以在编译时完成检查...
记住您可以像往常一样完美地重载函数模板。
这将依次解决两个问题:
operator!
(这不起作用)I know that code duplication is usually regarded as "bad", however in this case I would probably NOT use a runtime check to detect whether or not I passed an argument... whenever the check can be done at compile time...
Remember that you can perfectly overload functions templates as usual.
This will in turn solve the two problems:
operator!
on a lambda (which does not work)由于您已经使用了 C++0x 功能(lambda),因此只需使用另一个功能:默认模板参数
Since you're using C++0x features already (lambdas), just use another one: default template arguments
如何将第二个参数设置为非默认参数,并创建一个采用单个
typename Func
参数的重载包装方法。What about making the second parameter non-default, and creating an overloaded wrapper method that takes a single
typename Func
parameter.