Tôi đang cố gắng để làm cho công việc mã sau:chức năng Binding với đối số unique_ptr để std :: chức năng <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();
}
Gọi f() ràng buộc để Foo :: f2 (tham số cuối cùng là một con trỏ thô) hoạt động tốt, nhưng ràng buộc nó với Foo :: f1 gây ra lỗi biên dịch:
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
Tôi đang làm gì sai?
Tôi đang sử dụng gcc 4.8.2 và -std = C++ 0x (-std = C++ 11 thất bại quá) cờ.
Cảm ơn
Có vấn đề với việc chuyển giá trị tới std :: bind, xem http://stackoverflow.com/questions/4871273/passing-rvalues-through-stdbind F1 có thực sự cần có quyền sở hữu con trỏ không? f1 có thể lấy con trỏ bằng const ref và sau đó bạn có thể chuyển con trỏ tới std :: bind bằng cách sử dụng std :: ref http://coliru.stacked-crooked.com/a/5ebe39ccca544bea – countfromzero
Xem http://stackoverflow.com/ câu hỏi/9955714/không-stdbind-work-with-move-only-type-in-general-và-stdunique-ptr-in-part – zch
@justinls Yup, nó cần có quyền sở hữu, nhưng cảm ơn ví dụ của bạn. Nếu tôi không tìm cách để làm cho nó hoạt động bằng cách sử dụng std :: move, tôi sẽ đề xuất cách giải quyết bằng cách sử dụng đề xuất của bạn – rogerzanoni