Reputation: 42379
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 want 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?
Upvotes: 2
Views: 250
Reputation: 14461
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.
Upvotes: 0
Reputation: 146968
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) {
});
Upvotes: 2
Reputation: 14212
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.
Upvotes: 1