2017-03-10 2 views
2

J'essaie d'utiliser std::bind pour appeler std::reference_wrapper::get mais je n'arrive pas à le compiler. Je suis sûr que je néglige quelque chose d'évident mais les erreurs du compilateur ne m'aident pas. Ce code est artificiel et ne représente pas mon cas l'utilisation réelle:en utilisant std :: bind avec std :: reference_wrapper :: get

#include <functional> 
#include <iostream> 

struct A 
{ 
    void p() {std::cout << this << '\n';}; 
}; 

using ARef = std::reference_wrapper<A>; 

int main() 
{ 
    A a; 
    a.p(); 
    auto p = std::bind (&A::p, std::placeholders::_1); 
    p (a); // ok 

    ARef ar (a); 
    p (ar.get()); // ok 
    auto get = std::bind (&ARef::get, std::placeholders::_1); 
    p (get (ar)); // error 
} 

Edit: Cette compile très bien avec clang.

gcc 6.3.0 sortie:http://coliru.stacked-crooked.com/a/00bffc7549193cb8

main.cpp: In function 'int main()': 
main.cpp:21:19: error: no match for call to '(std::_Bind<std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>(std::_Placeholder<1>)>) (ARef&)' 
     p (get (ar)); // error 
       ^
In file included from main.cpp:1:0: 
/usr/local/include/c++/6.3.0/functional:989:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}] 
    operator()(_Args&&... __args) 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:989:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional:985:39: error: no match for call to '(std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)' 
    = decltype(std::declval<_Functor&>()(
       ~~~~~~~~~~~~~~~~~~~~~~~~~^ 
     _Mu<_Bound_args>()(std::declval<_Bound_args&>(), 
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     std::declval<tuple<_Args...>&>())...))> 
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true] 
    operator()(_Args&&... __args) const 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:985:39: required from here 
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)' 
    -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) 
       ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) 
    __invoke(_Callable&& __fn, _Args&&... __args) 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]' 
/usr/local/include/c++/6.3.0/functional:985:39: required from here 
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>' 
/usr/local/include/c++/6.3.0/functional:1003:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}] 
    operator()(_Args&&... __args) const 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:1003:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional:999:53: error: no match for call to '(const std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)' 
    = decltype(std::declval<typename enable_if<(sizeof...(_Args) >= 0), 
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
      typename add_const<_Functor>::type&>::type>()(
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true] 
    operator()(_Args&&... __args) const 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:999:53: required from here 
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)' 
    -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) 
       ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) 
    __invoke(_Callable&& __fn, _Args&&... __args) 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]' 
/usr/local/include/c++/6.3.0/functional:999:53: required from here 
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>' 
/usr/local/include/c++/6.3.0/functional:1017:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}] 
    operator()(_Args&&... __args) volatile 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:1017:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional:1013:70: error: no match for call to '(volatile std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)' 
    = decltype(std::declval<typename enable_if<(sizeof...(_Args) >= 0), 
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
         typename add_volatile<_Functor>::type&>::type>()(
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true] 
    operator()(_Args&&... __args) const 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:1013:70: required from here 
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)' 
    -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) 
       ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) 
    __invoke(_Callable&& __fn, _Args&&... __args) 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]' 
/usr/local/include/c++/6.3.0/functional:1013:70: required from here 
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>' 
/usr/local/include/c++/6.3.0/functional:1031:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}] 
    operator()(_Args&&... __args) const volatile 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:1031:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional:1027:64: error: no match for call to '(const volatile std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)' 
    = decltype(std::declval<typename enable_if<(sizeof...(_Args) >= 0), 
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
         typename add_cv<_Functor>::type&>::type>()(
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true] 
    operator()(_Args&&... __args) const 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:1027:64: required from here 
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)' 
    -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) 
       ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) 
    __invoke(_Callable&& __fn, _Args&&... __args) 
    ^~~~~~~~ 
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed: 
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]': 
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]' 
/usr/local/include/c++/6.3.0/functional:1027:64: required from here 
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>' 
+0

Pour aider les gens à répondre à votre question, vous devez être plus précis sur l'erreur. S'il vous plaît [modifier] votre message pour intégrer les erreurs exactes que vous obtenez de votre [mcve] (de préférence en utilisant copier + coller pour éviter les erreurs de transcription). –

+0

Peut-être que les erreurs du compilateur ne vous aident pas, mais ils pourraient peut-être nous aider. –

+0

compilé fin, gcc 4.8, Linux 0x7ffed79d12bf 0x7ffed79d12bf 0x7ffed79d12bf 0x7ffed79d12bf –

Répondre

5

Il est illégal de prendre l'adresse des fonctions membres de la bibliothèque standard, parce que implementations can add overloads and mutilate their signatures at will. Par conséquent, la bibliothèque standard, et en particulier the INVOKE protocol used by bind and friends, est conçue autour de l'hypothèse qu'il ne sera pas passé un pointeur au membre de std::reference_wrapper. L'appel d'un pointeur au membre pm avec reference_wrapperr équivaut à appeler pm avec r.get(); c'est-à-dire que la référence est inconditionnellement déballée.

Voir aussi LWG issue 2219, qui a ajouté reference_wrapper en gérant à INVOKE.

+0

Cela signifie-t-il que clang a tort de compiler ceci? Ou est-ce juste un comportement indéfini? – atb

+2

@atb C'est un comportement indéfini. –