【问题标题】:using std::bind with std::reference_wrapper::get使用 std::bind 和 std::reference_wrapper::get
【发布时间】:2017-07-31 23:40:30
【问题描述】:

我正在尝试使用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>'

【问题讨论】:

  • 为了帮助人们回答您的问题,您需要更具体地说明错误。请edit 您的帖子包含您从minimal reproducible example 获得的确切错误(最好使用复制+粘贴以避免转录错误)。
  • 也许编译器错误并不能帮助您,但它们也许可以帮助我们。
  • 编译正常,gcc 4.8,linux 0x7ffed79d12bf 0x7ffed79d12bf 0x7ffed79d12bf 0x7ffed79d12bf
  • @DenisZaikin 这是在科里鲁:coliru.stacked-crooked.com/a/00bffc7549193cb8
  • 似乎与 stdlib 有问题(或与之相关);如果你用clang++ -std=c++14 -O2 -Wall -stdlib=libc++ -pedantic -pthread main.cpp &amp;&amp; ./a.out 编译(所以用libc++ 而不是libstdc++),你程序编译并运行;但是如果你用clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp &amp;&amp; ./a.out 编译(所以用stdlibc++)你有一个类似的错误。我不知道如何正确

标签: c++ c++11 gcc functional-programming stdbind


【解决方案1】:

获取标准库成员函数的地址是非法的,因为implementations can add overloads and mutilate their signatures at will。因此,标准库,尤其是the INVOKE protocol used by bind and friends,是围绕它不会传递指向std::reference_wrapper 成员的指针这一假设而设计的。用reference_wrapperr 调用指向成员pm 的指针等效于用r.get() 调用pm;即,引用是无条件解包的。

另请参阅LWG issue 2219,它将reference_wrapper 处理添加到INVOKE

【讨论】:

  • 这是否意味着编译这个clang是错误的?还是只是未定义的行为?
  • @atb 这是未定义的行为。
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
相关资源
最近更新 更多