2012-04-14 27 views
6

Ai đó có thể giới thiệu một số cách sử dụng thực tế thú vị cho các tiện ích mem_fn và liên kết của tr1? Tôi không cần bí truyền c + + để phát triển thư viện. chỉ cần một số mã hóa cấp ứng dụng sử dụng chúng.một số ứng dụng thực tế của mem_fn & bind

bất kỳ trợ giúp nào sẽ được đánh giá cao.

Trả lời

5

Thông thường, việc sử dụng chức năng thành viên để gọi lại có thể khá phức tạp, ví dụ để sử dụng trong các chức năng <algorithm>. std::mem_fn (nó đã được chuẩn hóa ngay bây giờ, vì vậy bạn không cần phải sử dụng không gian tên tr1 nữa) tạo một đối tượng có thể gọi có thể được sử dụng làm đối tượng functor của các hàm đó. Ví dụ về việc sử dụng nó, xem phần ví dụ của this link sử dụng std::string::size.

std::bind có thể được sử dụng khi ví dụ: bạn không biết các đối số thực sự tại thời gian biên dịch, nhưng phải tạo một đối tượng có thể gọi với các đối số thời gian chạy. Nó cũng có thể được sử dụng để sắp xếp lại các đối số, ví dụ:

auto f1 = std::bind(printf, _2, _1); 
f1(42, "%d\n"); 

(Được rồi, ví dụ ngu ngốc, nhưng tất cả tôi có thể nghĩ ra ngay bây giờ.)

5

Tôi đã sử dụng std::mem_fnstd::bind đối với tài sản phản ánh phong cách.

Vì vậy, tôi sẽ có một class SomeClass có vectơ là AbstractProperty. Có thể có các loại khác nhau của các tầng lớp từ AbstractProperty, chẳng hạn như PropertyFloat, PropertyU32 vv

Sau đó, trong SomeClass tôi sẽ bind đến một std::function cho AbstractProperty. Tôi sẽ bind bằng cách làm

std::bind(std::mem_fn(&SomeClass::SomeFloatGetter), this) 

Đối với một hàm kiểu setter, tôi sẽ sử dụng

std::bind(std::mem_fn(&SomeClass::SomeSetterGetter), this, std::placeholders::_1) 

Tất nhiên, để thiết lập các chức năng đến lớp là khó khăn hơn, nhưng tôi sử dụng một std::function làm vì thế. Trong PropertyFloat Tôi có

typedef std::function<float(void)> GetterType; 

Vì vậy, nó thiết lập nó qua một chức năng, tôi sẽ vượt qua std::bind đầu tiên tôi đã giới thiệu như là tham số cho

typename PropertyFloat::GetterType getter 

Tất nhiên, các loại có thể tận dụng các mẫu và được chung chung hơn, nhưng đó là một thương mại tùy thuộc vào những gì bạn đang phát triển.

+0

+1. Đó là loại điều tôi muốn thử quá. Bạn có thêm chi tiết để chia sẻ về cách bạn đã thực hiện bit phản chiếu? – Fanatic23

+0

Hmm, đây là cơ bản nhất mà tôi có thể mô tả mà không cần phải đặt toàn bộ codebase lên github hoặc thứ gì đó (và mã nguồn là mã nguồn đóng). Tôi đã cập nhật bài đăng của mình để cung cấp thêm chi tiết. Thật không may, không có nhiều tài liệu cho loại hệ thống mà tôi đã phát triển ở đây. Tôi đang trong quá trình viết một tài liệu lớn trên toàn bộ hệ thống, nhưng nó vẫn chưa hoàn thành. Tôi có thể nói rằng tôi đã sử dụng 'std :: mem_fn' và' std :: bind' cho loại điều này trong gần hai năm mặc dù không có vấn đề gì. – josephthomas

+0

Ngoài ra không, đây là một trong những cách sử dụng phức tạp nhất của 'mem_fn' và' bind' mà tôi biết. Nếu bạn đang tìm cách để có được thực hành bằng cách sử dụng hai loại, có lẽ bạn nên xem xét một số tập quán nhỏ của chúng (tôi đã làm lúc đầu tiên trước khi tôi phát triển hệ thống này). Hệ thống phản xạ này được xây dựng xung quanh việc sử dụng hai loại này (và 'std :: function'). Mặc dù thành thật, điều này có thể được thay thế bằng con trỏ hàm thành viên (theo lý thuyết). Cả hai đều có lợi thế và bất lợi của họ. – josephthomas

3

Các mã sau đây đếm số phần tử lớn hơn năm:

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

int main() { 
    using namespace std; 
    vector<int> v { 1, 5, 2, 7, 6, 7, 5 }; 
    cout << count_if(v.begin(), v.end(), 
        bind(greater<int>(), placeholders::_1, 5)) << endl; 
} 
+0

Tại sao nên ràng buộc là một lựa chọn tốt hơn so với một hàm lambda trong ví dụ này? –

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