Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is std::remove_if with lambda predicate and auto element possible?

I'm assuming this is not possible because I got the following error:

error C3533: 'auto': a parameter cannot have a type that contains 'auto'

Here's a code snippet to reproduce the error:

int myInts[] = {1,2,3,3,3,4};
std::vector<int> myVec(myInts, myInts + sizeof(myInts)/sizeof(int));
myVec.erase(
    std::remove_if(myVec.begin(), myVec.end(),
        [](auto i){return i==3;}), // lambda param error
    myVec.end());

Now if you were to write this instead everything is fine and it will erase elements with the value of 3:

int myInts[] = {1,2,3,3,3,4};
std::vector<int> myVec(myInts, myInts + sizeof(myInts)/sizeof(int));
myVec.erase(
    std::remove_if(myVec.begin(), myVec.end(),
        [](int i){return i==3;}),
    myVec.end());

So can you simply not use auto as a function parameter as the error suggests?

Is this because the type of auto is determined by the rvalue which the compiler can't deduce despite it being a predicate of an algorithm executed on a known vector of int?

Does anyone know the reason?

like image 295
AJG85 Avatar asked Jun 13 '11 23:06

AJG85


3 Answers

Sadly, while this was suggested during the C++0x process, this ultimately never made it in. For simple functors, you may want to use something like Boost.Lambda (perhaps Phoenix v3 when it comes out, too), where the functors generated are polymorphic (and thus you don't need to specify anything):

std::remove_if(myVec.begin(), myVec.end(),
    _1 == 3)

The solution with type inference only:

// uses pass-by-reference unlike the question
std::remove_if(myVec.begin(), myVec.end(),
    [](decltype(myVec[0]) i){return i==3;})
like image 192
Luc Danton Avatar answered Oct 31 '22 09:10

Luc Danton


An auto is a type inference based on the value you're initialising it to. A parameter isn't initialised to anything at the place it appears in the code.

like image 28
Chris Jester-Young Avatar answered Oct 31 '22 07:10

Chris Jester-Young


Basically, this was already suggested, then rejected, and then lambdas were added in, so it very nearly made it in but happened not to, and is very likely to make it into the language in the future.

like image 44
Puppy Avatar answered Oct 31 '22 07:10

Puppy