C++ 迭代器缩减器模式,用于可能返回值也可能不返回值的函数
以下函数对每个元素应用一个函子并减少返回值:C++ 迭代器缩减器模式,用于可能返回值也可能不返回值的函数,c++,c++11,C++,C++11,以下函数对每个元素应用一个函子并减少返回值: template <class FCT, class RED> RED::TYPE forAllElements(FCT functor, RED reducer){ for(/* all elem in elements */){ reducer(functor(elem)); } return reducer.value; } 但这不会编译,因为我有reducer(functor(elem)),其中void函数的
template <class FCT, class RED>
RED::TYPE forAllElements(FCT functor, RED reducer){
for(/* all elem in elements */){
reducer(functor(elem));
}
return reducer.value;
}
但这不会编译,因为我有reducer(functor(elem))
,其中void函数的不存在的返回值作为参数
有没有一种方法可以使它在不复制void
和非void
情况下的元素的情况下对void函子起作用?
(对于怀疑XY问题的人:我基本上知道迭代和减少的不同方法,我认为提出的回调方法适合我的情况。我只是想知道如何避免“返回值+减少”和“仅回调”情况下出现重复代码。)我认为您可以创建一个
VoidReducer
类,而不是返回reducer.value
您需要返回reducer.getvalue()代码>。然后,只需使void VoidReducer::getvalue(){}
我还没有测试过这一点,但这个想法应该是可行的。允许您返回f()
如果f
和当前函数都有返回类型void
编辑
现在我更仔细地阅读了这个问题,我发现您要问的问题是行reducer(functor(elem))代码>
为此,我将基于decltype(functor(elem))
编译时分派
模板
无效组合(函子函子、减缩器和减缩器、Elem Elem、std::true\u类型)
{
函子(elem);
}
模板
无效组合(函子函子、减缩器和减缩器、Elem Elem、std::false\u类型)
{
还原子(函子(elem));
}
模板
无效组合(函子函子、减缩器和减缩器、元素元素)
{
组合(函子、减缩器、元素、std::is_same());
}
然后调用Combine
而不是reducer(functor(elem))
将正确地减少functor
的返回值,如果且仅当它不是无效的
PS:撒上引用和std::forward
调用来品尝味道。如果您仍然想使用for allelements
函数,那么如果直接使用std::for_each
,您可以创建一个不带减缩器的函数重载,只需在内部使用std::for_each
:
template <class FCT>
void forAllElements(FCT functor){
std::for_each(std::begin(...), std::end(...), functor);
}
...
forAllElements(FunctorThatReturnsNothing());
模板
元素的void(FCT函子){
std::for_each(std::begin(…),std::end(…),functor);
}
...
对于allelement(functorhatturnsnoothing());
如果无法为容器获取“迭代器”(如果使用非标准容器或指针),您当然可以拥有自己的循环,只需调用functor
一种干净灵活的方法是返回函数对象本身,而不是硬编码的值
字段
template <class FCT, class RED>
RED forAllElements(FCT functor, RED reducer){
for(/* all elem in elements */){
reducer(functor(elem));
}
return reducer;
}
模板
元素的红色(FCT函子,红色还原子){
对于(/*元素中的所有元素*/){
还原子(函子(elem));
}
回流减速机;
}
然后,该操作可以没有返回值,甚至可以有多个返回值,并带有信息性名称
您的原始方法可以看作是此基本组件上的方便包装器:
template <class FCT, class RED>
RED::TYPE forAllElements_convenience(FCT functor, RED reducer){
return forAllElements(functor, reducer).value;
}
模板
红色::类型为Allelements\u便利(FCT函子,红色减缩器){
返回元素(函子、减缩器).value;
}
那么基本上你想要什么?@JoachimPileborg,请参见问题的最后一部分,括号内。我知道我可以使用迭代器实现这一点,但在当前情况下,所提供的回调解决方案是有利的。最干净的方法是返回reducer
,而不是返回reducer.value
。你能重构你的代码来使用它吗?@filipos:这真是个好主意。我得检查一下这是否可能。
template <class FCT, class RED>
RED forAllElements(FCT functor, RED reducer){
for(/* all elem in elements */){
reducer(functor(elem));
}
return reducer;
}
template <class FCT, class RED>
RED::TYPE forAllElements_convenience(FCT functor, RED reducer){
return forAllElements(functor, reducer).value;
}