Domanda

I began implementing N3558 on top of libc++ master (see future here) but am now stuck with an error in functional, which I do not understand.

No matter how I code it, it always fails with the __compressed_pair error. I don't know whether I am missing something or it is a bug in libc++.

The following code:

#include <future>

struct test {
    test() {
        int someint = 0;
        std::promise<void> prom;
        auto fut = prom.get_future();
        fut.then( [this, someint]( std::future<void> future ) {
        } );
    }
};

triggers in clang 3.3:

In file included from /std/include/map:375:
/std/include/functional:993:11: error: no matching constructor for initialization of '__compressed_pair<<lambda at          /std/include/future:1096:14>, std::__1::allocator<<lambda at    /std/include/future:1096:14> > >'
    : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
      ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/std/include/functional:1278:26: note: in instantiation of member function 'std::__1::__function::__func<<lambda at /std/include/future:1096:14>, std::__1::allocator<<lambda at /std/include/future:1096:14> >, void ()>::__func' requested here
        ::new (__f_) _FF(_VSTD::move(__f));
                     ^
/std/include/__functional_base:341:37: note: in instantiation of function template specialization 'std::__1::function<void ()>::function<<lambda at /std/include/future:1096:14> >' requested here
return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...);
                                ^
/std/include/__config:301:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
          ^
/std/include/functional:1691:12: note: in instantiation of function template specialization 'std::__1::__invoke<const <lambda at /std/include/future:1144:17> &, const <lambda at /std/include/future:1096:14> &>' requested here
return __invoke(__f, __mu(get<_Indx>(__bound_args), __args)...);
       ^
/std/include/functional:1761:20: note: in instantiation of function template specialization 'std::__1::__apply_functor<const <lambda at /std/include/future:1144:17>, const std::__1::tuple<<lambda at /std/include/future:1096:14> >, 0, std::__1::tuple<> >' requested here
        return __apply_functor(__f_, __bound_args_, __indices(),
               ^
/std/include/future:1114:3: note: in instantiation of function template specialization 'std::__1::__bind<<lambda at /std/include/future:1144:17>, <lambda at /std/include/future:1096:14> >::operator()<>' requested here
            invoke_bind();
            ^
/std/include/future:1148:22: note: in instantiation of function template specialization 'std::__1::__then<void>::bind<std::__1::future<void>, <lambda at game/Game_local.cpp:1020:9>, <lambda at /std/include/future:1144:17> >' requested here
    return __then<_Rp>::bind( fut, forward<F>(execute_func), move(invoker) );
                        ^
/std/include/future:1527:34: note: in instantiation of function template specialization 'std::__1::__then<void>::bind_async<std::__1::future<void>, <lambda at game/Game_local.cpp:1020:9> >' requested here
{return __then<return_type>::bind_async( *this, std::forward<Function>(func) );}
                             ^
game/local.cpp:1020:3: note: in instantiation of function template specialization 'std::__1::future<void>::then<<lambda at game/Game_local.cpp:1020:9> >' requested here
    .then( [this, someint]( std::future<void> future ) {
     ^
/std/include/memory:2371:31: note: candidate constructor not viable: requires 0 arguments, but 3 were provided
_LIBCPP_INLINE_VISIBILITY __compressed_pair() {}
                          ^
/std/include/memory:2372:40: note: candidate constructor not viable: requires single argument '__t1', but 3 arguments were provided
_LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1)
                                   ^
/std/include/memory:2374:40: note: candidate constructor not viable: requires single argument '__t2', but 3 arguments were provided
_LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2)
                                   ^
/std/include/memory:2376:31: note: candidate constructor not viable: requires 2 arguments, but 3 were provided
_LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)
                          ^
/std/include/memory:2357:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 3 were provided
class __compressed_pair
  ^
/std/include/memory:2357:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 3 were provided

Compiling with gcc 4.8 gives a far uglier error message, but it's basically the same.

Could anyone shed some light?

È stato utile?

Soluzione

Basically, the interesting part happens when you try to invoke the binding of invoker from bind_async (future:1144). This lambda takes a std::function as an argument, but your binding has a lambda there. So it constructs the parameter from the lambda, which internally creates the type erasure subclass __function::__func. __func stores both the lambda and an allocator, and so as not to waste space when using a stateless allocator, it uses a __compressed_pair. So it tries to construct the compressed_pair with a piecewise_construct constructor, and fails to find one.

Why does it fail to find one? The constructor in question (in memory:2416) is under an #if block, specifically

#ifndef _LIBCPP_HAS_NO_VARIADICS

So I'm going to assume that somehow this symbol got defined in your build. Are you passing -std=c++11 to your compiler? If yes (and how else would all that other stuff compile?), maybe you need to double-check the config of libc++. In any case, you should try adding an #else to that preprocessor block above and putting an #error in there, to make sure that this is really the problem you're having.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top