Boost logo

Boost Users :

Subject: [Boost-users] [range] cannot use lambda predicate in adaptor with certain algorithms
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-05-30 04:12:35


Hello,
 
I get errors related to lambdas not being default-constructible or copy-assignable
when using a lambda as a predicate with certain adaptors (e.g. filtered) and
certain algorithms (e.g. min_element).
 
The following code illustrates the problem:
 
#include <boost/range/algorithm/min_element.hpp>
#include <boost/range/adaptor/filtered.hpp>
int main()
{
    int a[] = {1, 2, 3};
    auto is_odd = [](int i){ return i % 2 == 1; };
    boost::min_element(a | boost::adaptors::filtered(is_odd));
}

The errors are shown below.
 
Is there a workaround for this?
 
Thanks,
Nate.
 
Errors:

In file included from algorithm:63:0,
from /usr/lib/boost/boost/iterator/iterator_concepts.hpp:29,
from /usr/lib/boost/boost/range/concepts.hpp:20,
from /usr/lib/boost/boost/range/algorithm/min_element.hpp:15,
from test.cpp:1:
stl_algo.h: In function 'boost::filter_iterator<main()::<lambda(int)>, int *>
    min_element(
        boost::filter_iterator<main()::<lambda(int)>, int *>
      , boost::filter_iterator<main()::<lambda(int)>, int *>
    )':
/usr/lib/boost/boost/range/algorithm/min_element.hpp:44:63:
    instantiated from 'boost::range_iterator<const T>::ame boost
    ::range_iterator<const T>::type = boost::filter_iterator<
        main()::<lambda(int)>, int *
> boost::range::min_element(
        const boost::range_detail::filtered_range<
            main()::<lambda(int)>, int [3]
> &
    )'
test.cpp:8:61: instantiated from here
stl_algo.h:6109:4: error: use of deleted function 'boost::filter_iterator<
        main()::<lambda(int)>, int *
> & boost::filter_iterator<main()::<lambda(int)>, int *>::operator=(
        const boost::filter_iterator<main()::<lambda(int)>, int *> &
    )'
In file included from /usr/lib/boost/boost/range/adaptor/filtered.hpp
    :16:0,
from test.cpp:2:
/usr/lib/boost/boost/iterator/filter_iterator.hpp:44:9: error: 'boost
    ::filter_iterator<main()::<lambda(int)>, int *> & boost::filter_iterator<
        main()::<lambda(int)>, int *
>::operator=(
        const boost::filter_iterator<main()::<lambda(int)>, int *> &
    )' is implicitly deleted because the default definition would be ill-
    formed:
/usr/lib/boost/boost/iterator/filter_iterator.hpp:44:9: error: use of
    deleted function 'main()::<lambda(int)> & main()::<lambda(int)>::operator=(
        const main()::<lambda(int)> &
    )'
test.cpp:7:20: error: a lambda closure type has a deleted copy assignment
    operator
In file included from /usr/lib/boost/boost/range/adaptor/filtered.hpp
    :16:0,
from test.cpp:2:
/usr/lib/boost/boost/iterator/filter_iterator.hpp: In constructor
    'boost::filter_iterator<main()::<lambda(int)>, int *>::filter_iterator()':
/usr/lib/boost/boost/concept_check.hpp:133:10: instantiated from
    'boost::DefaultConstructible<
        boost::filter_iterator<main()::<lambda(int)>, int *>
>::~DefaultConstructible()'
/usr/lib/boost/boost/concept/usage.hpp:22:29: instantiated from
    'boost::concepts::usage_requirements<
        boost::DefaultConstructible<
            boost::filter_iterator<main()::<lambda(int)>, int *>
>
>::~usage_requirements()'
/usr/lib/boost/boost/concept/detail/general.hpp:38:28: instantiated
    from 'static void boost::concepts::requirement<
        boost::concepts::failed ************ boost::concepts
        ::usage_requirements<
            boost::DefaultConstructible<
                boost::filter_iterator<main()::<lambda(int)>, int *>
>
>::************
>::failed()'
/usr/lib/boost/boost/concept_check.hpp:132:1: instantiated from
    'boost::DefaultConstructible<
        boost::filter_iterator<main()::<lambda(int)>, int *>
>'
/usr/lib/boost/boost/range/concepts.hpp:169:16: instantiated from
    'boost::range_detail::ForwardIteratorConcept<
        boost::filter_iterator<main()::<lambda(int)>, int *>
>'
/usr/lib/boost/boost/concept/detail/has_constraints.hpp:42:5: [
    skipping 5 instantiation contexts ]
/usr/lib/boost/boost/concept/detail/has_constraints.hpp:42:5:
    instantiated from 'const bool boost::concepts::not_satisfied<
        boost::ForwardRangeConcept<
            const boost::range_detail::filtered_range<
                main()::<lambda(int)>, int [3]
>
>
>::value'
/usr/lib/boost/boost/concept/detail/has_constraints.hpp:45:31:
    instantiated from 'boost::concepts::not_satisfied<
        boost::ForwardRangeConcept<
            const boost::range_detail::filtered_range<
                main()::<lambda(int)>, int [3]
>
>
>'
/usr/lib/boost/boost/mpl/if.hpp:67:11: instantiated from 'boost::mpl
    ::if_<
        boost::concepts::not_satisfied<
            boost::ForwardRangeConcept<
                const boost::range_detail::filtered_range<
                    main()::<lambda(int)>, int [3]
>
>
>, boost::concepts::constraint<
            boost::ForwardRangeConcept<
                const boost::range_detail::filtered_range<
                    main()::<lambda(int)>, int [3]
>
>
>, boost::concepts::requirement<
            boost::concepts::failed ************ boost::ForwardRangeConcept<
                const boost::range_detail::filtered_range<
                    main()::<lambda(int)>, int [3]
>
>::************
>
>'
/usr/lib/boost/boost/concept/detail/general.hpp:50:8: instantiated
    from 'boost::concepts::requirement_<
        void (*)(
            boost::ForwardRangeConcept<
                const boost::range_detail::filtered_range<
                    main()::<lambda(int)>, int [3]
>
>
        )
>'
/usr/lib/boost/boost/range/algorithm/min_element.hpp:43:1:
    instantiated from 'boost::range_iterator<const T>::ame boost
    ::range_iterator<const T>::type = boost::filter_iterator<
        main()::<lambda(int)>, int *
> boost::range::min_element(
        const boost::range_detail::filtered_range<
            main()::<lambda(int)>, int [3]
> &
    )'
test.cpp:8:61: instantiated from here
/usr/lib/boost/boost/iterator/filter_iterator.hpp:54:25: error: use of
    deleted function 'main()::<lambda(int)>::<lambda>()'
test.cpp:7:20: error: a lambda closure type has a deleted default constructor


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net