2010-02-07 33 views
7

Cho một functor thích hợp để sử dụng với std::for_each và bạn bè:C++ functor để đầu ra iterator bộ chuyển đổi

template <typename T> struct Foo { 
    void operator()(T const& t) { ... } 
}; 

std::for_each(v.begin(), v.end(), Foo<Bar>()); 

Có một số cách tiêu chuẩn để chuyển đổi này vào một iterator đầu ra thích hợp để sử dụng với std::copy và bạn bè? (Hoặc thích ứng ngược lại) Một cái gì đó như:

std::copy(v.begin(), v.end(), functor_output_iterator(Foo<Bar>())); 

nào sẽ gọi functor mỗi lần một giá trị được gán cho các iterator:

adapter(F f) : functor(f) { } 
adapter& operator*() { return *this; } 
operator=(T const& t) { functor(t); } 
operator++()   { } 
... 

Hoặc cách khác:

std::for_each(..., some_adapter(std::ostream_iterator(std::cout))); 

Bối cảnh:

Tôi có một lớp học đó cho thấy nhiều một bộ sưu tập sử dụng một iterator đầu ra:

template <typename It> GetItems(It out) { 
    MutexGuard guard(mutex); 
    std::copy(items.begin(), items.end(), out); 
} 

Điều này cho phép người gọi để có được quyền truy cập vào các mục mà không buộc họ phải sử dụng một loại thùng chứa đặc biệt và không rối tung xung quanh với khóa hoặc các chi tiết nội bộ khác.

ví dụ, để có được sản phẩm chỉ duy nhất:

std::set<whatever> set; 
obj->GetItems(std::inserter(set, set.end())); 

này đánh bại địa ngục ra khỏi:

ObjLock lock = obj->GetLock(); 
for (int i = 0; i < obj->GetItemCount(); ++i) { 
    Item* item = obj->GetItem(i); 
    ... 

Bây giờ tôi cũng muốn để có thể tổng hợp các mặt hàng này, thay vì sao chép chúng. (Xem this question). Nơi tôi thường làm một cái gì đó như:

std::for_each(v.begin(), v.end(), Joiner<Foo>()); 

Bây giờ tôi có thể thực hiện hai phương pháp riêng biệt cho các phần tử dữ liệu giống nhau, người ta mà các cuộc gọi std::copy và một trong đó kêu gọi std::for_each nhưng nó sẽ được tốt đẹp để có thể xác định chỉ là một ví dụ phương pháp, sử dụng một trình lặp hoặc một hàm, và có người gọi có thể truyền hoặc là một hàm hoặc các trình vòng lặp tới nó, thích nghi chúng khi cần thiết cho loại thích hợp.

Điều tôi đang làm bây giờ là xác định trình tổng hợp theo cách sao cho nó có thể được sử dụng như một trình lặp đầu ra hoặc một hàm, nhưng điều này dẫn đến sự phức tạp không mong muốn.

+0

Vẫn không nhận được nó rất tốt ... for_each, như bạn chỉ ra, không sửa đổi các giá trị, vì vậy các nhà điều hành() được trở về void (không có gì), và chấp nhận một const T & (không thay đổi bất cứ điều gì) , vậy giá trị của phương thức sao chép sẽ được xuất ra là bao nhiêu? –

+0

@Diego Hàm functor không sửa đổi các đối số của nó, nhưng thay đổi trạng thái bên trong của nó. Không giống như một bản sao điển hình, đầu ra là trạng thái của functor, không phải là một loạt các phần tử. –

Trả lời

5

Làm thế nào về boost::function_output_iterator?

+0

Được rồi, điều đó thật đáng xấu hổ. Tôi nhìn ngay vào các tài liệu tăng cường lặp, và dường như bỏ qua ngay trên đó. Tôi đoán tôi đang tìm kiếm "functor" và không có gì khác. –

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