2015-05-07 24 views
7

Tôi gặp khó khăn trong việc tìm ra sự khác biệt giữa hai hàm bao hàm std::functionstd::mem_fn. Từ các mô tả, có vẻ như với tôi rằng std :: function hiện tất cả mọi thứ std::mem_fn hiện và nhiều hơn nữa. Trong trường hợp nào người dùng sẽ sử dụng std::mem_fn trên std::function?Sự khác nhau giữa std :: function và std :: mem_fn

+2

Bạn có nghĩa là 'std :: function' so với kiểu trả về' std :: mem_fn'? So sánh một mẫu lớp với một mẫu hàm không có ý nghĩa gì đối với tôi. – chris

Trả lời

19

Bạn thực sự không thể so sánh std::function với std::mem_fn. Trước đây là một mẫu lớp có kiểu bạn chỉ định, và sau đó là một mẫu hàm với kiểu trả về không xác định. Có thực sự không phải là một tình huống mà trong đó bạn thực sự xem xét một so với khác.

So sánh tốt hơn có thể là giữa mem_fnstd::bind. Ở đó, đối với trường hợp sử dụng cụ thể của một con trỏ tới thành viên, mem_fn sẽ tốn ít chi tiết hơn nếu tất cả những gì bạn muốn làm là truyền qua tất cả các đối số. Với loại hình này rất đơn giản:

struct A { 
    int x; 
    int getX() { return x; } 
    int add(int y) { return x+y; } 
}; 

A a{2}; 

Làm thế nào bạn sẽ làm cho một functor mà chỉ gọi getX() trên A được?

auto get1 = std::mem_fn(&A::getX); 
auto get2 = std::bind(&A::getX, _1); 

get1(a); // yields 2 
get2(a); // same 

Và có một đối số bổ sung cho add?

auto add1 = std::mem_fn(&A::add); 
auto add2 = std::bind(&A::add, _1, _2); 

add1(a, 5); // yields 7 
add2(a, 5); // same 

Vì vậy mem_fn ngắn gọn hơn trong trường hợp này. Tuy nhiên, nếu chúng ta muốn để ràng buộc một lập luận cụ thể, chẳng hạn gọi add(5) trên A nhất định, bạn chỉ có thể làm điều đó với bind:

auto add_5 = std::bind(&A::add, _1, 5); 
add_5(a); // yields 7 

Cuối cùng, không có so sánh giữa functionmem_fn, nhưng có những thời điểm thích mem_fn đến bind.

9

Trình bao bọc được trả về bởi std::mem_fn cực kỳ nhẹ; đó là một wrapper mỏng xung quanh một con trỏ đến thành viên.

std::function sử dụng loại tẩy xóa, nặng hơn rất nhiều.

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