How to simplify the tedious parameter declaration of lambdas in C++0x?
The simplest code is the best asker:
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> coll;
for_each(coll.begin(), coll.end(), [](vector<int>::value_type n) -> void {});
return 0;
}
Here, vector<int>::value_type n
is tedious. I wan开发者_运维百科t to have an auto-like utility to deduce the right type of n automatically; just like the following:
for_each(coll.begin(), coll.end(), [](auto_type n) -> void {});
To be more greedy, I want auto_type to take an argument used to deduce the right type of n. The argument can be a (smart) pointer or reference to the container, or an iterator of the container.
Dear gurus, how to implement that?
You don't have to declare the void return in that function. You could use decltype, like, decltype(coll[0])
.
std::for_each(coll.begin(), coll.end(), [](decltype(coll[0]) value) {
std::cout << value;
});
Edit:
template<typename T> auto type(T&& t) -> decltype(*std::forward<T>(t).begin()) {
return *t.begin();
}
std::for_each(coll.begin(), coll.end(), [](decltype(type(coll)) value) {
});
You should never write vector<int>::value_type instead of int, as you already know those are identical. A better example would help; I also would like simpler lambda parameters.
However, deducing parameter type depends on how the lambda is used, and that can only be known by knowing details of for_each. But function overload resolution depends on knowing the types of parameters, so parameter type cannot depend on how the function uses it, or you'd have a circular dependency.
In current C++, you avoid this circular dependency by decoupling the functor type from its parameter types:
struct AddExample {
template<class T>
T operator()(T a, T b) {
return a + b;
}
};
some_algo(begin, end, AddExample());
The equivalent could be done for the lambda syntax, at the cost of munging some semantics (e.g. implicit conversion to function pointers and std::function), but I don't see it happening for C++0x.
The early versions of the lambda proposal included provision for so-called polymorphic lambdas, with a simple syntax as follows:
auto print = [](x) { std::cout << x; };
print(42);
print("foo");
Unfortunately, there were technical issues in the proposal that the committee felt could not have been satisfactorily resolved given the already very tight schedule, so instead of standardizing a possibly broken feature, the introduction of polymorphic lambdas was deferred to a future standard revision.
精彩评论