首页 > 解决方案 > Boost.TypeErasure: movable functor

问题描述

Since std::function requires copy semantics and captured lambda cannot be converted to std::function, I try to define movable function using boost.TypeErasure. Everything is OK until move assign operator is required.

#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/constructible.hpp>
#include <boost/type_erasure/callable.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/mpl/vector.hpp>

namespace bte = boost::type_erasure;
namespace bm = boost::mpl;

using Foo = bte::any<
    bm::vector<
        bte::constructible<bte::_self(bte::_self&&)>,
        bte::assignable<bte::_self, bte::_self&&>,
        bte::destructible<>,
        bte::callable<void()>
    >
>;

int main()
{
    Foo{[&]{}};
}

With gcc, the compile error is:

In file included from /usr/local/include/boost/type_erasure/detail/normalize.hpp:34,

                 from /usr/local/include/boost/type_erasure/any.hpp:36,

                 from main.cpp:1:

/usr/local/include/boost/type_erasure/builtin.hpp: In instantiation of 'static void boost::type_erasure::assignable<T, U>::apply(T&, const U&) [with T = main()::<lambda()>; U = main()::<lambda()>&&]':

/usr/local/include/boost/type_erasure/detail/instantiate.hpp:91:9:   required from 'static void boost::type_erasure::detail::instantiate_concept4::apply(Concept*, Map*) [with Concept = boost::mpl::vector<boost::type_erasure::constructible<boost::type_erasure::_self(boost::type_erasure::_self&&)>, boost::type_erasure::assignable<boost::type_erasure::_self, boost::type_erasure::_self&&>, boost::type_erasure::destructible<>, boost::type_erasure::callable<void()> >; Map = boost::mpl::map1<boost::mpl::pair<boost::type_erasure::_self, main()::<lambda()> > >]'

/usr/local/include/boost/type_erasure/any.hpp:225:13:   required from 'boost::type_erasure::any<Concept, T>::any(U&&) [with U = main()::<lambda()>; Concept = boost::mpl::vector<boost::type_erasure::constructible<boost::type_erasure::_self(boost::type_erasure::_self&&)>, boost::type_erasure::assignable<boost::type_erasure::_self, boost::type_erasure::_self&&>, boost::type_erasure::destructible<>, boost::type_erasure::callable<void()> >; T = boost::type_erasure::_self]'

main.cpp:21:14:   required from here

/usr/local/include/boost/type_erasure/builtin.hpp:73:51: error: use of deleted function 'main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&)'

     static void apply(T& dst, const U& src) { dst = src; }

                                               ~~~~^~~~~

main.cpp:21:11: note: a lambda closure type has a deleted copy assignment operator

     Foo{[&]{}};

           ^

I don't understand why apply's argument is const. And what is the correct way?

Coliru link

Update:

I thought lambda is move-assignable. However, it seems wrong.

标签: c++lambdaboost-type-erasure

解决方案


推荐阅读