C++11 lambdas

J

Jerry

This works fine:

int main()
{
std::map<std::string,std::string> parameters;

parameters["abc"]="def";

std::for_each(parameters.begin(),parameters.end(),
[] (std::map<std::string,std::string>::value_type& pair)
{std::cout << pair.first << "=" << pair.second << " ";});

return 0;
}

But g++ 4.6.0 doesn't like it when I change the type of pair in the
lambda to auto:

int main()
{
std::map<std::string,std::string> parameters;

parameters["abc"]="def";

std::for_each(parameters.begin(),parameters.end(),
[] (auto pair)
{std::cout << pair.first << "=" << pair.second << " ";});

return 0;
}

So, my question is: why can't it be auto?

In general I am most interested in why the committee chooses to
include things or not and I figure there must be a reason this isn't
allowed. Or is it allowed and my compiler is just too old?

Thanks,

Jerry
 
L

Lucien Coffe

Jerry wrote :
This works fine:

int main()
{
std::map<std::string,std::string> parameters;

parameters["abc"]="def";

std::for_each(parameters.begin(),parameters.end(),
[] (std::map<std::string,std::string>::value_type& pair)
{std::cout << pair.first << "=" << pair.second << " ";});

return 0;
}

But g++ 4.6.0 doesn't like it when I change the type of pair in the
lambda to auto:

int main()
{
std::map<std::string,std::string> parameters;

parameters["abc"]="def";

std::for_each(parameters.begin(),parameters.end(),
[] (auto pair)
{std::cout << pair.first << "=" << pair.second << " ";});

return 0;
}

So, my question is: why can't it be auto?

In general I am most interested in why the committee chooses to include
things or not and I figure there must be a reason this isn't allowed.
Or is it allowed and my compiler is just too old?

Thanks,

Jerry

Auto knows its type from its initializer. Here there are no initializer.
It is used for *convenience*. I may be wrong, but I think this is not
possible because of this.

Here is an example of why : http://ideone.com/pP5jz
/error: parameter declared 'auto'/
 
J

Juha Nieminen

Jerry said:
So, my question is: why can't it be auto?

Not (yet) a C++11 expert, but in general function parameters cannot be
of type 'auto'. The function signature would depend on the type of the
given parameter, and it would basically be a templated function in that
case.

Of course this raises two interesting questions:

1) Can lambdas be templatized? I honestly don't know.

2) Why can't the compiler "auto-templatize" a function that takes a
parameter of type 'auto'? (In other words, implicitly make it a template
function where the parameter marked as 'auto' is a templated type.)
I guess this would open a pandora's box of complications, and for dubious
benefit (after all, it would just save a "template" declaration and little
else).
 
M

Miles Bader

Juha Nieminen said:
2) Why can't the compiler "auto-templatize" a function that takes a
parameter of type 'auto'? (In other words, implicitly make it a template
function where the parameter marked as 'auto' is a templated type.)

I seem to recall that this was considered, along with the same thing
("implicit templates") for ordinary functions, and came sort of close to
getting in, but was decided to be just a bit too much for the current
standard. Soooo maybe in a future standard.

There's some discussion of it here (search for "polymorphic lambdas"):

http://channel9.msdn.com/Shows/Going+Deep/Herb-Sutter-C-Questions-and-Answers

-Miles
 
N

Noah Roberts

  Not (yet) a C++11 expert, but in general function parameters cannot be
of type 'auto'. The function signature would depend on the type of the
given parameter, and it would basically be a templated function in that
case.

  Of course this raises two interesting questions:

  1) Can lambdas be templatized? I honestly don't know.

No. You can create them within templates though, which could serve
much the same purpose:

template < typename T >
function<void(T const&)> printer() { return [](T const& t) { ... }; }
 
J

Juha Nieminen

Noah Roberts said:
No. You can create them within templates though, which could serve
much the same purpose:

template < typename T >
function<void(T const&)> printer() { return [](T const& t) { ... }; }

But that kind of defeats the major advantage of lambdas (and one of the
main reasons they were introduced): To be able to write small functions
"inline". You could perfectly well write that function without the lambda
and use it for the same purpose.
 
V

Victor Bazarov

Noah Roberts said:
No. You can create them within templates though, which could serve
much the same purpose:

template< typename T>
function<void(T const&)> printer() { return [](T const& t) { ... }; }

But that kind of defeats the major advantage of lambdas (and one of the
main reasons they were introduced): To be able to write small functions
"inline". You could perfectly well write that function without the lambda
and use it for the same purpose.

Jeez, you're going to pick on anything, aren't you? Imagine a template
a bit bigger than a one-line function. Say, a 100-line function. Or a
class. In one of the class template's member functions you can still
write a lambda that will depend on the template argument and as such
will exist in as many variations (generated by the compiler) as there
are template instantiations. That's what Noah was trying to show you.

V
 
C

ChuanQi Tan

I thank you can think like this:

lambdas was a function that compiler do it for you, so you cannot declare a function that have a "auto" type argument

void (auto pair)
{
...
}

I think compiler cannot work!
 
J

Jerry

I thank you can think like this:

lambdas was a function that compiler do it for you, so you cannot declarea function that have a "auto" type argument

void (auto pair)
{
   ...

}

I think compiler cannot work!

Yes, I would never have considered doing this with a free function
because its obvious that the compiler wouldn't know. And yet in the
lambda it seemed to be such a good idea even thought it obviously the
same exact thing.

Thanks,

Jerry
 
M

Miles Bader

Jerry said:
Yes, I would never have considered doing this with a free
function because its obvious that the compiler wouldn't know.
And yet in the lambda it seemed to be such a good idea even
thought it obviously the same exact thing.

In the case of a named function, "void fun (auto x) { ... }"
would basically be a more natural syntax for
"template<typename T> void fun (T x) { ... }"

It's discussed here:

http://channel9.msdn.com/Shows/Going+Deep/Herb-Sutter-C-Questions-and-Answers

[Summary: both were considered and came close to getting in the
standard, but didn't go in for practical reasons.]

-Miles
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top