I'm trying to write a function like std::for_each
, that in addition to the normal usage, can also take a std::function<bool (param)>
. A false return value means that I want to break out of the loop. The code below is what I've gotten so far.
The second call to a.visit([&](int) -> void)
does not compile when evaluating !visitor(i). Is it possible to make this work or am I barking up the wrong tree?
I'm using MSVC 2010 but want the code to be generally C++11 compatible.
#include <list>
#include <string>
#include <iostream>
struct A
{
std::list<int> _lst;
template<typename _F>
void visit(_F visitor)
{
for(std::list<int>::const_iterator it = _lst.begin(), end = _lst.end() ; it != end ; it++) {
int i = *it;
if (std::is_void<decltype(visitor(i))>::value) {
visitor(i);
} else {
if (!visitor(i)) { // <----- error C2171: '!' : illegal on operands of type 'void'
break;
}
}
}
}
};
int main(int argc, char* argv[])
{
A a;
// populate a
for (int i = 0 ; i < 10 ; i++) {
a._lst.push_back(i);
}
a.visit([](int i) -> bool {
std::cout << i << std::endl;
return i < 5;
});
a.visit([](int i) {
std::cout << i << std::endl;
});
}
The return type for a lambda is specified using a C++ feature named 'trailing return type'. This specification is optional. Without the trailing return type, the return type of the underlying function is effectively 'auto', and it is deduced from the type of the expressions in the body's return statements.
A Python lambda function behaves like a normal function in regard to arguments. Therefore, a lambda parameter can be initialized with a default value: the parameter n takes the outer n as a default value.
The lambda function can take many arguments but can return only one expression.
In Kotlin, the lambda expression contains optional part except code_body.
Here's how I would implement for_almost_each
; I'm using namespace std
plus type aliases for readability purposes.
#include <algorithm>
#include <iterator>
#include <functional>
using namespace std;
template<class Iter, class Func>
Iter
for_almost_each_impl(Iter begin, Iter end, Func func, std::true_type)
{
for (auto i = begin; i!=end; ++i)
if (!func(*i))
return i;
return end;
}
template<class Iter, class Func>
Iter
for_almost_each_impl(Iter begin, Iter end, Func func, std::false_type)
{
for_each(begin, end, func);
return end;
}
template<class Iter, class Func>
Iter for_almost_each(Iter begin, Iter end, Func func)
{
using Val = typename iterator_traits<Iter>::value_type;
using Res = typename result_of<Func(Val)>::type;
return for_almost_each_impl(begin, end,
func,
is_convertible<Res, bool>{} );
}
I used is_convertible
, as it seems to make more sense than is_same
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With