与shared_ptr一起使用g ++ std :: bind错误

时间:2012-12-19 19:05:48

标签: c++ c++11 g++ bind shared-ptr

我无法理解为什么以下代码无法编译。

#include <memory>
#include <functional>

class Foo 
{
public:
  void Bar(int i) {}
};

void X(std::function<void(std::shared_ptr<Foo>)> f)
{

}

int main()
{
  std::shared_ptr<Foo> f(new Foo);
  auto f1(std::bind(&Foo::Bar, std::placeholders::_1, 1));
  X(f1);
  return 0;
}

g ++(4.6.3)输出......

n file included from /usr/include/c++/4.6/memory:80:0,
                 from test.cpp:1:
/usr/include/c++/4.6/functional: In static member function ‘static void std::_Function_handler<void(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Functor = std::_Bind<std::_Mem_fn<void (Foo::*)(int)>(std::_Placeholder<1>, int)>, _ArgTypes = {std::shared_ptr<Foo>}]’:
/usr/include/c++/4.6/functional:2148:6:   instantiated from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = std::_Bind<std::_Mem_fn<void (Foo::*)(int)>(std::_Placeholder<1>, int)>, _Res = void, _ArgTypes = {std::shared_ptr<Foo>}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<void(std::shared_ptr<Foo>)>::_Useless]’
test.cpp:19:7:   instantiated from here
/usr/include/c++/4.6/functional:1778:2: error: no match for call to ‘(std::_Bind<std::_Mem_fn<void (Foo::*)(int)>(std::_Placeholder<1>, int)>) (std::shared_ptr<Foo>)’
/usr/include/c++/4.6/functional:1130:11: note: candidates are:
/usr/include/c++/4.6/functional:1201:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}, _Result = _Result, _Functor = std::_Mem_fn<void (Foo::*)(int)>, _Bound_args = {std::_Placeholder<1>, int}]
/usr/include/c++/4.6/functional:1215:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}, _Result = _Result, _Functor = std::_Mem_fn<void (Foo::*)(int)>, _Bound_args = {std::_Placeholder<1>, int}]
/usr/include/c++/4.6/functional:1229:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = std::_Mem_fn<void (Foo::*)(int)>, _Bound_args = {std::_Placeholder<1>, int}]
/usr/include/c++/4.6/functional:1243:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = std::_Mem_fn<void (Foo::*)(int)>, _Bound_args = {std::_Placeholder<1>, int}]

1 个答案:

答案 0 :(得分:5)

这是一个GCC错误,我在4.7中修复过,但我不记得究竟是哪个错误。我会试着弄清楚......

编辑:啊哈,PR 55463因此在4.7中没有固定,它只在GCC主干上固定(4.8将是什么)

错误是mem_fn返回的调用包装器不接受rvalues,而std::function<void(std::shared_ptr<Foo>)类型将{rvalue shared_ptr<Foo>传递给bind的调用包装器返回值

作为一种解决方法,您可以将功能签名更改为:

void X(std::function<void(const std::shared_ptr<Foo>&)> f)

我认为我不能将修复程序向后移植到4.7分支,因为由于该错误,我对mem_fn进行了一些非常大的更改,这些更改并不适合稳定版本分支(I还在标准中找到了新的defect