6

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?

AJG85
  • 15,849
  • 13
  • 42
  • 50

3 Answers3

8

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.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • I get the same error when defaulting the value of an `auto` parameter in a function so I guess that's not enough but that was kind of expected. – AJG85 Jun 14 '11 at 00:06
8

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;})
Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • 1
    Last I heard, Boost.Phoenix v3 is the official replacement for Boost.Lambda (and eventually Boost.Bind), so given that Boost.Lambda has no future it would be better to start with Phoenix v2 (or wait for v3) and ignore Boost.Lambda altogether. – ildjarn Jun 14 '11 at 00:07
  • nifty, we use boost so that's an option but I've been trying to get familiar with C++0x features recently. – AJG85 Jun 14 '11 at 00:16
  • @AJG86 There is no C++0x feature that allows creating polymorphic functors on the fly -- although your particular problem only needs type inference to be solved, not full-on polymorphism – Luc Danton Jun 14 '11 at 00:18
2

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.

Puppy
  • 144,682
  • 38
  • 256
  • 465