2009-05-07 29 views
12

Tôi có một vectơ con trỏ không thuộc sở hữu của vùng chứa. Làm cách nào để sử dụng các thuật toán trên các mục tiêu của con trỏ. Tôi đã cố gắng sử dụng ptr_vector của boost, nhưng nó cố gắng xóa các con trỏ khi nó nằm ngoài phạm vi.làm cách nào để sử dụng thuật toán STL với vectơ của con trỏ

Dưới đây là một số mã mà cần phải làm việc:

vector<int*> myValues; 
// ... myValues is populated 
bool consistent = count(myValues.begin(), myValues.end(), myValues.front()) == myValues.size(); 
auto v = consistent ? myValues.front() : accumulate(myValues.begin(), myValues.end(), 0)/myValues.size(); 
fill(myValues.begin(), myValues.end(), v); 
// etc. 

Tôi nhận ra rằng cho vòng sẽ làm việc, nhưng điều này sẽ xảy ra trong một loạt các nơi, do đó một số loại bộ chuyển đổi unary? Tôi đã không thể tìm thấy một. Cảm ơn trước!

+0

Nếu bạn sử dụng các tính năng của tiêu chuẩn C++ chưa được phê duyệt trong tương lai, bạn sẽ giới hạn câu trả lời bạn nhận được. Nó là rất không rõ ràng nếu câu hỏi của bạn là về thư viện tiêu chuẩn hiện tại, việc sử dụng Boost, hoặc các tính năng mới của C++ 0x. –

+0

Có vẻ như v được cho là giá trị trung bình của các int, nhưng sau đó dòng sao chép cố gắng sao chép vào v, do đó v sẽ phải là một con trỏ hoặc trình lặp. –

+0

ồ vâng, dòng cuối cùng là sai ... Tôi muốn viết "điền" thay vì "sao chép". –

Trả lời

19

Bạn có thể sử dụng Boost Indirect Iterator. Khi được tham chiếu (với operator*()), nó áp dụng thêm dereference, vì vậy bạn kết thúc với giá trị được trỏ bởi con trỏ được tham chiếu bởi trình lặp. Để biết thêm thông tin, bạn cũng có thể xem this question about a dereference iterator.

Dưới đây là một ví dụ đơn giản:

std::vector<int*> vec; 

vec.push_back(new int(1)); 
vec.push_back(new int(2)); 

std::copy(boost::make_indirect_iterator(vec.begin()), 
      boost::make_indirect_iterator(vec.end()), 
      std::ostream_iterator<int>(std::cout, " "));  // Prints 1 2 
+0

Đây chính xác là những gì tôi đang tìm kiếm, cảm ơn! –

+0

ồ, tốt đẹp, đó là câu hỏi của bạn - cách để truyền đạt kiến ​​thức;) –

0

Bạn có thể xem boost::shared_ptr<> - con trỏ thông minh có tính tham chiếu. Nó sẽ không xóa con trỏ sau khi nó nằm ngoài phạm vi.

+0

vấn đề là các con trỏ là biến thành viên trong các đối tượng khác. Tôi cũng có thể biến chúng thành shared_ptr, nhưng đó có thể không phải là cách hiệu quả nhất để làm điều này. –

3
bool consistent = count_if(myValues.begin(), myValues.end(), 
    bind2nd(ptr_fun(compare_ptr), *myValues.front())) == myValues.size(); 

int v = consistent ? *myValues.front() : accumulate(
    myValues.begin(), myValues.end(), 0, sum_int_ptr)/myValues.size(); 

for_each(myValues.begin(), myValues.end(), bind1st(ptr_fun(assign_ptr),v)); 

Fill không thể lấy chức năng gán (vì vậy mà nó sẽ dereference con trỏ). Do đó for_each() đã được sử dụng. Để tối ưu hóa nó sẽ là khôn ngoan để thêm nếu (! Phù hợp) trước khi chạy for_each(). Các chức năng được sử dụng ở trên một lớp lót STL:

int sum_int_ptr(int total, int * a) { return total + *a; }  
void assign_ptr(int v, int *ptr) { *ptr = v; }  
bool compare_ptr(int* a, int pattern) { return *a == pattern; } 
+1

Cảm ơn, tôi đã học được rất nhiều từ câu trả lời của bạn. Tôi có lẽ sẽ đi với các vòng lặp gián tiếp tăng ở đây, nhưng nó là tốt đẹp để biết làm thế nào để sử dụng bind1st, bind2nd, và như vậy. –

+0

yeah STL là khá mạnh mẽ, nó là giá trị biết tất cả những một lót như tích lũy, vv –

+1

PS .: Giá trị đọc: http://www.keithschwarz.com/cs106l/fall2007/handouts/200_STL_Functional_Library.pdf –

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