带有lambda谓词和auto元素的std::remove_if是否可行

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

本文关键字:remove if 是否 std 谓词 lambda auto 元素 带有      更新时间:2023-10-16

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

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的类型是由右值决定的吗?尽管它是在int的已知向量上执行的算法的谓词,但编译器无法推导出该右值?

有人知道原因吗?

遗憾的是,虽然这是在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;})

auto是一种基于初始化值的类型推断。参数在代码中出现的位置不会初始化为任何值。

基本上,这已经被建议,然后被拒绝,然后添加了lambdas,所以它几乎成功了,但碰巧没有成功,而且很可能在未来成为语言。