Đúng cách để xác định một chức năng Predicate trong C ++


0 Phiếu
Đã hỏi 04/4/2016 bởi doesntFix (930 điểm)
Tôi đang cố gắng để viết predicate function để sử dụng với các thuật toán STL. Tôi thấy rằng họ đang có hai cách để xác định một vị ngữ: (1) sử dụng một function đơn giản như dưới đây:
bool isEven(unsigned int i)   
{ return (i%2 == 0); }
std::find_if(itBegin, itEnd, isEven); 
(2) sử dụng operator() function như dưới đây:
class checker {  
public:  
  bool operator()(unsigned int i)  
  { return (i%2 == 0); }  
}; 
std::find_if(itBegin, itEnd, checker); 
tôi có thể sử dụng cho lần thứ hai type như tôi thường muốn tạo ra một object predicate với một số thành viên trong nó và sử dụng chúng trong các thuật toán. Khi tôi thêm function isEven cùng bên trong kiểm tra và sử dụng nó như một vị ngữ, tôi nhận được một lỗi: 3. cú pháp mà mang lại cho lỗi:
class checker { 
    public: 
       bool isEven(unsigned int i) 
       { return (i%2 == 0); }
}; 
checker c; 
std::find_if(itBegin, itEnd, c.isEven); 
điện thoại c. isEven cung cấp cho một error trong compilation nói undefined tham chiếu đến một số chức năng. Ai đó có thể giải thích lý do tại sao 3. là đem lại cho lỗi? Ngoài ra, tôi sẽ đánh giá cao bất kỳ con trỏ để đọc về khái niệm cơ bản vị ngữ và iterator.

2 Câu trả lời

0 Phiếu
Đã trả lời 07/4/2016 bởi pub_to (640 điểm)
checker::isEven không phải là một chức năng; nó là một chức năng member . Và bạn không thể gọi function -tĩnh member mà không có một tham chiếu đến một đối tượng checker. Vì vậy, bạn không thể chỉ cần sử dụng một function member ở bất kỳ nơi cũ mà bạn có thể vượt qua một con trỏ function . Thành viên liên kết có syntax đặc biệt đòi hỏi nhiều hơn là chỉ () để gọi. Đó là lý do tại sao functors sử dụng operator(); Điều này làm cho object callable mà không cần phải sử dụng một con trỏ chỉ function member .
Đã bình luận 08/4/2016 bởi Gun_That (252,760 điểm)
Xem compiler của bạn là hiện đại, đủ để hỗ trợ bằng cách sử dụng một lambda, một cái gì đó như: ' std::find_if (itBegin, itEnd, [] (int i) {trở về tôi %2 == 0;}); `.
Đã bình luận 08/4/2016 bởi However (580 điểm)
-cảm ơn... có vẻ như một ý tưởng cool. Nhưng tôi đoán chúng ta đang mất code tái sử dụng cho syntax kỳ lạ:). Nếu tôi có một functor, tôi có thể tái sử dụng sau này, và nó dễ dàng hơn để duy trì
0 Phiếu
Đã trả lời 16/4/2016 bởi when6005 (200 điểm)
Tôi đoán đó là bởi vì type c.isEven(),
bool (checker::*)(unsigned int) // member function of class
mà không có thể được dự kiến bởi find_if(). std::find_if nên mong đợi hoặc là một function pointer (bool (*)(unsigned int)) hoặc một đối tượng function . chỉnh : một hạn chế: một-static member function pointer phải được gọi là class object . Trong trường hợp của bạn, ngay cả khi bạn thành công để vượt qua member function sau đó find_if() vẫn sẽ không có bất kỳ thông tin nào về bất kỳ đối tượng checker; Vì vậy, nó không có ý nghĩa để có quá tải cho việc chấp nhận một đối số pointer member function find_if(). lưu ý : nói chung c.isEven là không đúng cách để vượt qua các con trỏ function member ; nó nên được thông qua như là &checker::isEven.
Đã bình luận 18/4/2016 bởi Vfa_7266 (1,510 điểm)
Vâng... nếu bạn có một functor thực sự đứng một cơ hội tốt đang được sử dụng ở nhiều nơi, sau đó một lambda không thể là con đường tốt nhất. Cùng một lúc, cho code tầm thường như thế này, lợi ích từ việc có nó có thể nhìn thấy tất cả trực tiếp có thể lớn hơn những mất mát (có thể) từ lặp đi lặp lại. Cùng lúc đó, tôi phải thêm rằng có lẽ tốt nhất là * không * suy nghĩ của syntax như "kỳ lạ"--tiêu chuẩn mới bao gồm đó đang được hoàn thành và trình biên dịch mới nhất đã hỗ trợ nó; Hy vọng sớm gặp lại nó trong sử dụng rộng rãi.
Đã bình luận 18/4/2016 bởi ner868 (260 điểm)
Vâng... nếu bạn có một functor thực sự đứng một cơ hội tốt đang được sử dụng ở nhiều nơi, sau đó một lambda không thể là con đường tốt nhất. Cùng một lúc, cho code tầm thường như thế này, lợi ích từ việc có nó có thể nhìn thấy tất cả trực tiếp có thể lớn hơn những mất mát (có thể) từ lặp đi lặp lại. Cùng lúc đó, tôi phải thêm rằng có lẽ tốt nhất là * không * suy nghĩ của syntax như "kỳ lạ"--tiêu chuẩn mới bao gồm đó đang được hoàn thành và trình biên dịch mới nhất đã hỗ trợ nó; Hy vọng sớm gặp lại nó trong sử dụng rộng rãi.

ToughDev Q&A là gì?

Trang web hỏi đáp cho các bạn đam mê lập trình, phát triển phần mềm và các vấn đề kỹ thuật khác. Với sự giúp đỡ của bạn, chúng tôi hy vọng sẽ xây dựng thành công một thư viện đầy đủ các câu hỏi và trả lời về tất cả các vấn đề có liên quan đến lập trình!







...