是否有关于诸如erase / remove_if之类的算法的编程标准以及remove_if实现的可能副作用?

时间:2018-01-18 18:14:21

标签: c++ language-lawyer stl-algorithm side-effects

我有一个弱指针向量,如果指针仍然存在,想要查看该列表并执行一个函数。如果指针消失了,我想删除它。

class my_class
{
public:
    std::shared_ptr<my_class>    pointer_t;
    std::weak_ptr<my_class>      weak_pointer_t;
    ...

private:
    ...
};

class listeners_class
{
public:
    typedef std::vector<my_class::weak_ptr>  listeners_t;
    ...

private:
    listeners_t    f_listeners;
    ...
};

我注意到我可以直接在remove_if()测试函数中实现它,因为remove_if()实际上遍历整个向量并尝试锁定弱指针。加上这种方式更加原子

有lambda的代码。

    f_listeners.erase(
        std::remove_if(
              f_listeners.begin()
            , f_listeners.end()
            , [&ptr](my_class::weak_pointer_t l)
            {
                my_class::pointer_t ll(l.lock());
                if(ll == nullptr)
                {
                    return true;
                }
                ll->some_callback(ptr);  // <<-- side effect!
                return false;
            })
        );

我认为这是不好的做法,但想确认是否有关于此类代码的标准形式。

1 个答案:

答案 0 :(得分:2)

标准未指定实施。但是,只要您不关心每个元素的预测函数的评估顺序,我们就可以从标准中推导出您的代码将按预期工作。

首先,[alg.remove]

  

效果:消除以下相应条件所适用的[ifirst范围内的迭代器last引用的所有元素:{ {1}},*i == value

     

...

     

复杂性:相应谓词的pred(*i) != false个应用程序。

这些约束保证预测函数对每个元素执行一次

其次,[res.on.data.races]/8

  

除非另有说明,否则C ++标准库函数应仅在当前线程内执行所有操作,如果这些操作具有用户可见的效果。

关于the comment in [intro.execution]/11

  

换句话说,函数执行不会相互交错。

因此,您可以考虑在某种意义上执行预测函数原子。