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

时间:2011-06-13 23:58:27

标签: c++ stl lambda c++11

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

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

以下是重现错误的代码段:

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());

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

那么你可以根本不使用auto作为函数参数吗?

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

有谁知道原因?

3 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:8)

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

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

仅限类型推断的解决方案:

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

答案 2 :(得分:2)

基本上,这已经被提出,然后被拒绝,并且然后 lambdas被添加进来,所以它几乎使它成为但是碰巧没有,并且很可能将它变成语言未来。