C++ 如何处理可选参数的模板类型名?
首先,守则:C++ 如何处理可选参数的模板类型名?,c++,templates,lambda,c++11,C++,Templates,Lambda,C++11,首先,守则: 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(skipUnkn
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);
}
}
模板
void ForEachField(Func normalHandler,Func2 arrayHandler=NULL,bool skipUnknowns=true)
{
对于(int i=0;iIsUnknown())
继续;
如果(f->GetCount()==1 | |!arrayHandler)
(f);
其他的
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
df->ForEachField(
[&](字段*字段){f ForEachField(
[&](字段*字段){WriteLine(f,格式(“\t\t'%s'=>array('type'=>'%s'),”)%Field->GetName()%Field->GetTypeInfo()->Name);
});//不起作用
第二个电话不起作用,因为它说:
OutputPhp.cpp(27):错误C2783:'无效
数据文件::ForEachField(Func,Func2,bool)'
:无法推断模板参数
对于“Func2”
请参阅“DataFile::ForEachField”的声明
在仍然使用模板并且不必手动指定第二个模板参数的情况下,有什么方法可以使第二个参数成为可选的吗?既然您已经在使用C++0x功能(lambdas),只需使用另一个:默认模板参数
template<typename Func, typename Func2 = void*>
void ForEachField(Func normalHandler, Func2 arrayHandler = NULL, bool skipUnknowns = true)
模板
void ForEachField(Func normalHandler,Func2 arrayHandler=NULL,bool skipUnknowns=true)
您可以为ForEachField
添加重载:
template<typename Func>
void ForEachField (Func normalHandler)
{
ForEachField<Func, void *>(normalHandler, NULL, true);
}
模板
void ForEachField(Func normalHandler)
{
ForEachField(normalHandler,NULL,true);
}
将第二个参数设为非默认值,并创建一个重载的包装器方法,该方法接受一个typename Func
参数。我知道代码重复通常被认为是“坏的”,但是在这种情况下,我可能不会使用运行时检查来检测我是否传递了参数…只要检查可以在编译时完成
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); }
}
}
模板
void ForEachField(Func normalHandler,Func2 arrayHandler,bool skipUnknowns=true)
{
对于(int i=0;iIsUnknown()){continue;}
如果(f->GetCount()==1){normalHandler(f);}
else{arrayHandler(f);}
}
}
模板
void ForEachField(Func normalHandler,bool skipUnknowns=true)
{
对于(int i=0;iIsUnknown()){continue;}
如果(f->GetCount()==1){normalHandler(f);}
}
}
请记住,您可以像往常一样完全重载函数模板
这将反过来解决两个问题:
- 第二个参数现在是可选的(用于所有目的)
- 不再在lambda上应用
(不起作用)操作符!
错误C4519:只允许在类模板上使用默认模板参数
必须是g++和MSVC++之间的差异。它在g++上工作。是的,MSVC还不支持这一点。(由于两个编译器都不支持C++0x的主要部分,所以说“只使用另一个C++0x功能”有点乐观):)这实际上是个好主意。显然它应该是ForEachField
,否则我会遇到同样的问题;)但现在我遇到了另一个问题..!如果arrayHandler是一个lambda,arrayHandler不起作用,现在试图找到一个解决方案:哦,原来的版本确实编译了,尽管我没有运行它。