Ich versuche, den folgenden Code funktioniert:Binding Funktionen mit unique_ptr Argumente std :: function <void()>
#include <cstdio>
#include <functional>
#include <string>
#include <memory>
using namespace std;
class Foo {
public:
Foo(): m_str("foo") { }
void f1(string s1, string s2, unique_ptr<Foo> p)
{
printf("1: %s %s %s\n", s1.c_str(), s2.c_str(), p->str());
}
void f2(string s1, string s2, Foo* p)
{
printf("2: %s %s %s\n", s1.c_str(), s2.c_str(), p->str());
}
const char* str() const { return m_str.c_str(); }
private:
string m_str;
};
int main()
{
string arg1 = "arg1";
string arg2 = "arg2";
Foo s;
unique_ptr<Foo> ptr(new Foo);
//function<void()> f(bind(&Foo::f1, &s, arg1, arg2, std::move(ptr)));
function<void()> f(bind(&Foo::f2, &s, arg1, arg2, ptr.release()));
f();
}
Aufruf f(), gebunden an Foo :: f2 (letzte Parameter ist ein Rohzeiger) funktioniert gut, aber die Bindung an Foo :: f1 verursacht Kompilierung Fehler:
test.cpp: In function ‘int main()’:
test.cpp:36:70: error: no matching function for call to ‘std::function<void()>::function(std::_Bind_helper<false, void (Foo::*)(std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>), Foo*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::unique_ptr<Foo, std::default_delete<Foo> > >::type)’
function<void()> f(bind(&Foo::f1, &s, arg1, arg2, std::move(ptr)));
^
test.cpp:36:70: note: candidates are:
In file included from test.cpp:2:0:
/usr/include/c++/4.8.2/functional:2251:2: note: template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor)
function(_Functor);
^
/usr/include/c++/4.8.2/functional:2251:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.8.2/functional:2226:7: note: std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {}]
function(function&& __x) : _Function_base()
^
/usr/include/c++/4.8.2/functional:2226:7: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (Foo::*)(std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>), Foo*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::unique_ptr<Foo, std::default_delete<Foo> > >::type {aka std::_Bind<std::_Mem_fn<void (Foo::*)(std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>)>(Foo*, std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>)>}’ to ‘std::function<void()>&&’
/usr/include/c++/4.8.2/functional:2429:5: note: std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]
function<_Res(_ArgTypes...)>::
^
/usr/include/c++/4.8.2/functional:2429:5: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (Foo::*)(std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>), Foo*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::unique_ptr<Foo, std::default_delete<Foo> > >::type {aka std::_Bind<std::_Mem_fn<void (Foo::*)(std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>)>(Foo*, std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>)>}’ to ‘const std::function<void()>&’
/usr/include/c++/4.8.2/functional:2206:7: note: std::function<_Res(_ArgTypes ...)>::function(std::nullptr_t) [with _Res = void; _ArgTypes = {}; std::nullptr_t = std::nullptr_t]
function(nullptr_t) noexcept
^
/usr/include/c++/4.8.2/functional:2206:7: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (Foo::*)(std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>), Foo*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::unique_ptr<Foo, std::default_delete<Foo> > >::type {aka std::_Bind<std::_Mem_fn<void (Foo::*)(std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>)>(Foo*, std::basic_string<char>, std::basic_string<char>, std::unique_ptr<Foo>)>}’ to ‘std::nullptr_t’
/usr/include/c++/4.8.2/functional:2199:7: note: std::function<_Res(_ArgTypes ...)>::function() [with _Res = void; _ArgTypes = {}]
function() noexcept
^
/usr/include/c++/4.8.2/functional:2199:7: note: candidate expects 0 arguments, 1 provided
Was mache ich falsch?
Ich benutze gcc 4.8.2 und -std = C++ 0x (-std = C++ 11 fehlschlägt auch) Flags.
Dank
Es gibt Probleme mit der Weitergabe von rvalues an std :: bind, siehe http://stackoverflow.com/questions/4871273/passing-rvalues-through-stdbind Benötigt f1 wirklich Besitz von dem Zeiger? f1 könnte den Zeiger durch const ref nehmen und dann können Sie den Zeiger auf std :: bind übergeben mit std :: ref http://coliru.stacked-crooked.com/a/5ebe39ccca544bea – countfromzero
Siehe http://stackoverflow.com/ Fragen/9955714/does-stdbind-arbeiten-mit-bewegen-nur-types-in-general-und-stdunique-ptr-in-part – zch
@justinls Yup, muss es Besitz übernehmen, aber danke für Ihr Beispiel. Wenn ich keinen Weg finden kann, um es mit std :: move funktionieren zu lassen, schlage ich eine Umgehung mit Ihrem Vorschlag vor. – rogerzanoni