是否可以使用lambda谓词和auto元素的std :: remove_if?

AJG*_*G85 6 c++ lambda stl c++11

我假设这是不可能的,因为我收到以下错误:

error C3533: 'auto': a parameter cannot have a type that contains 'auto'
Run Code Online (Sandbox Code Playgroud)

这是重现错误的代码片段:

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());
Run Code Online (Sandbox Code Playgroud)

现在如果你要写这个而不是一切都很好,它会擦除​​值为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());
Run Code Online (Sandbox Code Playgroud)

那么你可以简单地不用auto作函数参数,因为错误暗示了吗?

这是因为类型auto是由rvalue决定的,编译器无法推断它尽管它是在已知向量上执行的算法的谓词int

有谁知道原因?

Chr*_*ung 8

An auto是基于您初始化它的值的类型推断.参数未在代码中出现的位置初始化为任何内容.


Luc*_*ton 8

遗憾的是,虽然这是在C++ 0x过程中提出的,但最终从未进入过.对于简单的仿函数,你可能想要使用像Boost.Lambda这样的东西(也许是Phoenix v3,当它出来时),其中的仿函数生成的是多态的(因此您不需要指定任何内容):

std::remove_if(myVec.begin(), myVec.end(),
    _1 == 3)
Run Code Online (Sandbox Code Playgroud)

仅具有类型推断的解决方案:

// uses pass-by-reference unlike the question
std::remove_if(myVec.begin(), myVec.end(),
    [](decltype(myVec[0]) i){return i==3;})
Run Code Online (Sandbox Code Playgroud)