2013-03-20 31 views
59

Ai đó có thể đưa ra một ví dụ đơn giản thể hiện chức năng của std::ref? Tôi có nghĩa là một ví dụ trong đó một số cấu trúc khác (như tuple, hoặc mẫu kiểu dữ liệu) được sử dụng chỉ khi không thể giải thích std::ref mà không có chúng.Điều gì sẽ là "Xin chào, Thế giới!" ví dụ cho "std :: ref"?

Tôi đã tìm thấy hai câu hỏi về std::refherehere. Nhưng trong lần đầu tiên nó đi về một lỗi trong trình biên dịch và trong ví dụ thứ hai, ví dụ về việc sử dụng std::ref không chứa std::ref và chúng liên quan đến các mẫu dữ liệu và kiểu dữ liệu giúp hiểu rõ các ví dụ phức tạp.

+4

http://en.cppreference.com/w/cpp/utility/functional/ref – inf

Trả lời

79

Bạn nên suy nghĩ của việc sử dụng std::ref khi một hàm:

  • mất một tham số mẫu theo giá trị
  • hoặc bản sao/di chuyển một tham số chuyển tiếp tài liệu tham khảo như std::bind hoặc các nhà xây dựng cho std::thread .

std::ref là loại giá trị hoạt động giống như tham chiếu.

Ví dụ này sử dụng khả năng minh họa std::ref.

#include <iostream> 
#include <functional> 

void increment(int &x) 
{ 
    ++x; 
} 

int main() 
{ 
    int i = 0; 

    // Here, we bind increment to (a copy of) i... 
    std::bind(increment, i)(); 
    //      ^^ (...and invoke the resulting function object) 

    // i is still 0, because the copy was incremented. 
    std::cout << i << std::endl; 

    // Now, we bind increment to std::ref(i) 
    std::bind(increment, std::ref(i))(); 

    // i has now been incremented. 
    std::cout << i << std::endl; 
} 

Output:

0 
1 
+3

Có lẽ đáng để chỉ ra rằng 'std :: ref' là rebindable, không giống như một tài liệu tham khảo thông thường, mà có thể quan trọng nếu bạn đang ăn một trong một chức năng mẫu. Xem http://stackoverflow.com/questions/37101301/is-this-stdref-behaviour-logical để biết ví dụ. –

15
void PrintNumber(int i) {...} 

int n = 4; 
std::function<void()> print1 = std::bind(&PrintNumber, n); 
std::function<void()> print2 = std::bind(&PrintNumber, std::ref(n)); 

n = 5; 

print1(); //prints 4 
print2(); //prints 5 

std::ref được sử dụng chủ yếu để đóng gói tài liệu tham khảo khi sử dụng std::bind (nhưng sử dụng khác có thể xảy ra tất nhiên).

6

Một nơi khác mà bạn có thể cần std :: ref là khi truyền các đối tượng đến các chuỗi mà bạn muốn mỗi luồng hoạt động trên một đối tượng và không phải là bản sao của đối tượng.

int main(){ 
BoundedBuffer buffer(200); 

std::thread c1(consumer, 0, std::ref(buffer)); 
std::thread c2(consumer, 1, std::ref(buffer)); 
std::thread c3(consumer, 2, std::ref(buffer)); 
std::thread p1(producer, 0, std::ref(buffer)); 
std::thread p2(producer, 1, std::ref(buffer)); 

c1.join(); 
c2.join(); 
c3.join(); 
p1.join(); 
p2.join(); 

return 0; } 

nơi bạn muốn các chức năng khác nhau chạy trong các chủ đề khác nhau để chia sẻ một đối tượng đệm duy nhất. Ví dụ này đã bị đánh cắp từ hướng dẫn tuyệt vời này (C++11 Concurrency Tutorial - Part 3: Advanced locking and condition variables (Baptiste Wicht) ) (hy vọng tôi đã thực hiện phân bổ chính xác)

+0

Lý do để sử dụng 'std :: ref' ở đây, là hàm tạo của' thread' yêu cầu một kiểu tham số 'std :: reference_wrapper' – Deqing

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