[英]std::reference_wrapper does not work nicely with std::bind
[英]using std::bind with std::reference_wrapper::get
我正在嘗試使用std::bind
調用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
}
編輯:這可以用clang編譯。
gcc 6.3.0輸出: 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>'
獲取標准庫成員函數的地址是非法的,因為實現可能會增加重載並隨意破壞其簽名 。 因此,標准庫,尤其是bind
和friends使用的INVOKE
協議 ,是基於以下假設設計的:它不會傳遞指向std::reference_wrapper
成員的指針。 使用reference_wrapper
r
調用指向成員pm
的指針等效於使用r.get()
調用pm
; 也就是說,該引用是無條件展開的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.