Lambda Works on Latest Visual Studio, but Doesn't Work Elsewhere

后端 未结 1 413
一向
一向 2020-12-19 04:48

So I\'ve written a nasty lambda to satisfy a \"shortest amount of code necessary to achieve this\" question:

values.resize(distance(
    begin(values),
    r         


        
相关标签:
1条回答
  • 2020-12-19 05:26

    You are relying on the fact that the exact closure you pass into the algorithm is the one used as the predicate, but the standard allows it to be copied:

    [algorithms.general]/10 (N4140): [Note: Unless otherwise specified, algorithms that take function objects as arguments are permitted to copy those function objects freely. Programmers for whom object identity is important should consider using a wrapper class that points to a noncopied implementation object such as reference_wrapper (20.9.3), or some equivalent solution. —end note ]

    This is exactly what libstdc++ does. From v6.2.1:

    template<typename _ForwardIterator, typename _Predicate>
    _ForwardIterator
    __remove_if(_ForwardIterator __first, _ForwardIterator __last,
                _Predicate __pred)
    {
        __first = std::__find_if(__first, __last, __pred);
        if (__first == __last)
        return __first;
        _ForwardIterator __result = __first;
        ++__first;
        for (; __first != __last; ++__first)
        if (!__pred(__first))
            {
            *__result = _GLIBCXX_MOVE(*__first);
            ++__result;
            }
        return __result;
    }
    

    That call to std::__find_if at the start of the function copies __pred, which means that the value of i is incremented a bit within std::__find_if, but this doesn't change what's going on at the call site.

    To fix this problem, you could use std::ref:

    auto clos = [i = 0U, it = cbegin(intervals), end = cend(intervals)](const auto&) mutable {
        return it != end && ++i > it->first && (i <= it->second || (++it, true));
    };
    values.resize(distance(begin(values), std::remove_if(begin(values), end(values), std::ref(clos))));
    

    Live demo

    0 讨论(0)
提交回复
热议问题