tags:

views:

97

answers:

2

Is it possible to capture by const reference in a lambda expression?

I want the assignment marked below to fail, for example:

#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string strings[] = 
    {
        "hello",
        "world"
    };
    static const size_t num_strings = sizeof(strings)/sizeof(strings[0]);

    string best_string = "foo";

    for_each( &strings[0], &strings[num_strings], [&best_string](const string& s)
      {
        best_string = s;    // this should fail
      }
    );
    return 0;
}
+2  A: 

const isn't in the grammar for captures as of n3092:

capture:
  identifier
  & identifier
  this

The text only mention capture-by-copy and capture-by-reference and doesn't mention any sort of const-ness.

Feels like an oversight to me, but I haven't followed the standardization process very closely.

Steve M
+2  A: 

I guess if you're not using the variable as a parametter of the functor, then you should use the access level of the current function. If you think you shouldn't, then separate your lambda from this function, it's not part of it.

Anyway, you can easily achieve the same thing that you want by using another const reference instead :

#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string strings[] = 
    {
        "hello",
        "world"
    };
    static const size_t num_strings = sizeof(strings)/sizeof(strings[0]);

    string best_string = "foo";
    const string& string_processed = best_string;

    for_each( &strings[0], &strings[num_strings], [&best_string]  (const string& s)  -> void 
    {
        string_processed = s;    // this should fail
    }
    );
    return 0;
}

But that's the same as assuming that your lambda have to be isolated from the current function, making it a non-lambda.

Klaim
The capture clause still mentions `best_string` only. Apart from that, GCC 4.5 "successfully rejects" the code like intended.
sellibitze
Yes, this would give me the results I was trying to achieve on a technical level. Ultimately however, the answer to my original question seems to be "no."
John Dibling
Why would that make it a "non-lambda"?
Roger Pate
Because the nature of a lambda is that it's context-dependant. If you don't need a specific context then it's just a quick way to make a functor. If the functor should be context-independant, make it a real functor.
Klaim