以下函数在每个元素上应用仿函数并减少返回值:
template <class FCT, class RED>
RED::TYPE forAllElements(FCT functor, RED reducer){
for(/* all elem in elements */){
reducer(functor(elem));
}
return reducer.value;
}
现在,有时我可能只想在所有元素上调用functor
,而不是减少任何内容。基本上,我希望有类似的东西:
class FunctorThatReturnsNothing{
void operator() (Elem e){
// do something, return nothing...
}
}
class DummyReducer{
using TYPE = void; // ??? something like that ???
template <class FCT>
void operator() (/* ??? what here */){
// do nothing...
}
}
forAllElements(FunctorThatReturnsNothing(), DummyReducer());
但是由于我有reducer(functor(elem))
,因此我不会编译,其中将void函数的不存在的返回值作为参数。
有没有办法让它适用于无效仿函数,而不会为void
和非void
情况重复forAllElements?
(对于怀疑XY问题的人:我基本上知道不同的迭代和减少方法,我认为所提出的回调方法适合我的情况。我只是想知道如何避免重复代码为&# 34;返回值+减少&#34;以及&#34;只是回调&#34;情况。)
答案 0 :(得分:1)
我认为您可以制作VoidReducer
课程,但不需要return reducer.value;
,而是需要return reducer.getvalue();
。然后你只需制作void VoidReducer::getvalue(){}
。
我还没有对此进行过测试,但这个想法应该可行。如果return f();
和当前函数都返回f
类型,则允许void
。
修改强>
现在我更仔细地阅读了这个问题,我发现你问的问题是reducer(functor(elem));
行。
为此,我将根据decltype(functor(elem))
进行编译时调度。
template <class Functor, class Reducer, class Elem>
void Combine(Functor functor, Reducer & reducer, Elem elem, std::true_type)
{
functor(elem);
}
template <class Functor, class Reducer, class Elem>
void Combine(Functor functor, Reducer & reducer, Elem elem, std::false_type)
{
reducer(functor(elem));
}
template <class Functor, class Reducer, class Elem>
void Combine(Functor functor, Reducer & reducer, Elem elem)
{
Combine(functor, reducer, elem, std::is_same<decltype(functor(elem)), void>());
}
然后调用Combine
代替reducer(functor(elem))
会正确地减少functor
的返回值,当且仅当它不是无效时。
PS:为参考品添加参考和std::forward
电话。
答案 1 :(得分:1)
如果您仍然希望使用forAllElements
函数而不是直接使用std::for_each
,则可以创建不带减速器的函数重载,并在内部使用std::for_each
:
template <class FCT>
void forAllElements(FCT functor){
std::for_each(std::begin(...), std::end(...), functor);
}
...
forAllElements(FunctorThatReturnsNothing());
如果无法为容器获取“迭代器”(如果使用非标准容器或指针),您当然可以拥有自己的循环,只需调用functor
。
答案 2 :(得分:0)
一种干净而灵活的方法是返回函数对象本身,而不是硬编码的value
字段。
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;
}