2013-04-23 45 views
5

ràng buộc tôi có mã này:std :: chức năng và std :: hành vi

#include <iostream> 
#include <functional> 
#include <vector> 

void fun() 
{ 
    std::cout<<"fun"; 
} 

void gun(int) 
{ 
    std::cout<<"gun"; 
} 

int main() 
{ 
    std::vector<std::function<void(int)>> vec; 

    vec.push_back(std::bind(fun)); 
    vec.push_back(gun); 

    vec[0](1); 
    vec[1](2); 
} 

bạn có thể vui lòng giải thích làm thế nào nó có thể cho std::bind trở std::function<void(int)> khi ràng buộc void() chức năng?

Làm cách nào để gọi hàm void() bằng cách sử dụng void(int) functor?

+1

giống như một nitpick: vui lòng cung cấp tất cả các câu lệnh '# include' cần thiết trong mẫu mã của bạn (vectơ, iostreams, chức năng). Làm cho nó thuận tiện hơn nhiều để sao chép-dán. – TemplateRex

Trả lời

9

Chữ ký được chuyển làm đối số mẫu cho function chỉ xác định số lượng người giữ chỗ (_1) sẽ bị ràng buộc và loại nào.

Việc triệu gọi hàm thực tế chỉ sử dụng số lượng đối số thực sự được yêu cầu bởi hàm bị ràng buộc. Trong thực tế, các tham số thừa được bỏ qua. (?)

khác, làm sáng tỏ hơn ví dụ, nhìn vào điều này từ phía bên kia:

#include <iostream> 
#include <functional> 

void gun(int i) 
{ 
    std::cout<<"gun("<<i<<")"; 
} 

int main() 
{ 
    using namespace std::placeholders; 
    std::bind(gun, _5)("ignore", 3, "and", 4, 43); 
} 

Prints

gun(43) 
+0

Tôi xin lỗi nhưng điều này không trả lời câu hỏi của tôi: làm thế nào std :: bind có thể làm cho x params chức năng x + k params std :: function? Rõ ràng làm thế nào nó có thể làm từ x + k params chức năng x params std :: function. – Felics

+0

@Felics là hoàn toàn thẳng thắn, câu trả lời nghiêm ngặt sẽ là: "đó là thực hiện được xác định" - tiêu chuẩn không chỉ định cách 'std :: function' được triển khai, hoặc, cho rằng kiểu trả về của' std: : bind'. Vì vậy, nếu bạn thực sự muốn biết ** cách thực hiện **, hãy thực hiện. Tôi nghĩ bạn đã hỏi về nó một cách khái niệm, và tôi nghĩ tôi đã trả lời điều đó. – sehe

+0

@Felics cũng xem [câu hỏi này] (http://stackoverflow.com/questions/13251976/why-do-objects-returned-from-bind-ignore-extra-arguments) – TemplateRex

0

Làm thế nào nó có thể gọi void() chức năng bằng cách sử dụng void(int) functor?

std::bind(fun) không trả về hàm void(), hàm này trả về trình bao bọc cuộc gọi không xác định.

Cách thông thường để gọi rằng wrapper cuộc gọi sẽ có không tranh cãi, nhưng trong hầu hết các trường của bind() loại có thể được gọi với zero hoặc nhiều đối số và các đối số bổ sung sẽ được bỏ qua (tức là không được thông qua với mục tiêu chức năng)

Thông thường, đối với hàm F lấy N đối số, bind(F) trả về một trình bao bọc cuộc gọi có thể được gọi với N hoặc nhiều đối số. Nếu bạn ràng buộc đối số hoặc sử dụng trình giữ chỗ thì nó sẽ thay đổi số lượng đối số tối thiểu cần thiết để gọi trình bao bọc cuộc gọi.

Các vấn đề liên quan