如何根据另一个向量中的条目从向量中删除元素?

时间:2018-11-01 05:26:03

标签: c++ stl shared-ptr

我已经搜索了stackoverflow并找到了我问题的部分答案: How to remove elements from a vector based on a condition in another vector? 在我的情况下,我有两个向量,一个包含整数,一个包含共享指针(std :: shared_ptr ),我无法弄清楚指针的算法使代码正常工作。

class someAbstractClass
{     
};

class someClass : public someAbstractClass
{
};    

std::vector<int> condition;
std::vector<std::shared_ptr< someAbstractClass >> container;

condition.push_back(0);
condition.push_back(1);
condition.push_back(0);

container.push_back( std::make_shared< someClass > );
container.push_back( std::make_shared< someClass > );
container.push_back( std::make_shared< someClass > );

std::erase( std::remove_if( container.begin(), conatiner.end(),
           [&] ( const std::shared_ptr< someAbstractClass > &s ) 
           { 
               return condition[ &s - &(*container.begin()) ] == 1;
           } ), container.end() );

有没有办法使这项工作成功?

1 个答案:

答案 0 :(得分:0)

您正在将shared_ptr个对象进行比较。您需要比较这些对象的地址。而且lambda需要通过 reference 接受其输入参数,以确保其与向量中的原始对象的地址配合使用,而不与内存中其他位置的对象的 copy 配合使用

container.erase(
    std::remove_if(
        container.begin(), container.end(),
        [&](const std::shared_ptr<someType> &s) {
            return condition[ &s - &(*container.begin()) ] == 1;
        }
    ),
    container.end()
);

Live Demo

将其与您链接到的the accepted answerthe question中的以下代码段进行比较:

a.erase(remove_if(begin(a), end(a),
    [b&](const myClass& d) { return b[&d - &*begin(a)].alive(); }),
    end(a));

看到相似之处吗?

减去连续{em> 内存容器中两个有效元素的 typed 地址,例如std::vector,会在两个元素之间产生偏移。当较低地址用于容器的第一个元素时,该偏移量实际上与较高地址的索引相同。这样,本例中的指针算法便能够获取condition中的lambda参数的索引(前提是condition至少具有与container一样多的元素)。