Có lý do cụ thể nào để không có std :: copy_if algorithm trong C++ không? Tôi biết tôi có thể sử dụng std :: remove_copy_if để đạt được các hành vi cần thiết. Tôi nghĩ rằng nó đang đến trong C + + 0x, nhưng một copy_if đơn giản mà mất một phạm vi, một iterator đầu ra và một functor sẽ có được tốt đẹp. Nó chỉ đơn giản là bỏ lỡ hoặc là có một số lý do khác đằng sau nó?Tại sao không có thuật toán std :: copy_if?
Trả lời
Theo "Ngôn ngữ lập trình C++ của Stroustrup", nó chỉ là một cảnh tượng quá mức.
(như là một trích dẫn, cùng một câu hỏi đã trả lời trong thúc đẩy thư danh sách: copy_if)
Như một bản cập nhật, tiêu chuẩn C++ 11 đã sửa lại sự giám sát này bằng cách thêm một 'copy_if' mới Thuật toán: http://en.cppreference.com/w/cpp/algorithm/copy –
Multiplesourcesindicate rằng nó bị bỏ rơi do STL gây ra.
Tuy nhiên, tôi không chắc đó có phải là sự thật hay là một huyền thoại vĩnh viễn. Tôi sẽ đánh giá cao nếu bất cứ ai sẽ chỉ ra một nguồn đáng tin cậy hơn một liên kết đến một bài ngẫu nhiên trên Internet.
Đây là bài đăng không phải ngẫu nhiên trên internet, được chọn dựa trên cơ sở mà nó xác nhận là một email từ Stroustrup vào danh sách gửi thư Boost: http://lists.boost.org/Archives/boost/2001/01/8030.php. Tất nhiên nó có thể là một gian lận, hoặc nó có thể là Stroustrup mình đã mua huyền thoại. Tôi đoán có thể là Stepanov thường nghĩ rằng tốt nhất nên có 'remove_copy_if', và cố ý loại trừ' copy_if' thành dư thừa.Nhưng nghiêm túc, rõ ràng là có một loại sai lầm nào đó để có 'remove_copy_if' nhưng không phải là' copy_if', nếu chỉ có một hương vị :-) –
Stroustrup nói họ đã quên nó. Đó là trong C++ 11.
Tuy nhiên, bạn có thể sử dụng remove_copy_if
(thực tế nên được gọi là copy_if_not
) cùng với not1
thay thế.
Trong tâm trí của tôi, tôi luôn dịch "remove_copy_if" thành "copy_except" :) – StackedCrooked
... miễn là bạn sẵn sàng chấp nhận điều đó :: not1 không tương thích với con trỏ hàm. (Như tôi thấy đã được thảo luận dưới đây ...) –
Đó là chết dễ dàng để viết riêng của bạn:
template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred)
{
return std::remove_copy_if(first,last,result,std::not1(pred));
}
Edit: phiên bản này hoạt động với tất cả các vị từ:
template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred)
{
while(first!=last)
{
if(pred(*first))
*result++ = *first;
++first;
}
return result;
}
Điều này không thực sự chính xác, như được ghi trong * Hiệu quả STL * mục 36, bởi vì nó chỉ hoạt động trên functors thích nghi. – rlbond
có vẻ như nó không phải là chết dễ dàng, có vẻ như nỗ lực thứ hai của bạn trả về giá trị đầu tiên phù hợp với vị ngữ - bên cạnh đó, IMHO, bạn là một chút off-topic ở đây – rotoglup
rotoglup - Tôi sợ rằng bạn không biết những gì bạn đang nói về. 'result' là một OutputIterator. Tôi đã kiểm tra mã này bạn biết. –
Chỉ cần cho đầy đủ, trong trường hợp ai đó Googles/cách của mình để câu hỏi này, cần lưu ý rằng bây giờ (bài C++ 11) có một thuật toán copy if. Nó hoạt động như mong đợi (sao chép các phần tử trong một phạm vi, mà một số biến vị ngữ trả về true, đến một phạm vi khác).
Một trường hợp sử dụng điển hình sẽ là
std::vector<int> foo{ 25, 15, 5, -5, -15 };
std::vector<int> bar;
// copy only positive numbers:
auto it = std::copy_if (foo.begin(), foo.end(), std::back_inserter(bar),
[](int i){return !(i<0);
});
Chỉ cần cho đầy đủ tôi sẽ bổ sung tăng mà có boost::algorithm::copy_if
cho những người bạn của những người không thể sử dụng C++ phiên bản 11 của (như tôi) trong boost/algorithm/cxx11/copy_if.hpp
mà sẽ sử dụng std::copy_if
khi :
#if __cplusplus >= 201103L
// Use the C++11 versions of copy_if if it is available
using std::copy_if; // Section 25.3.1
#else
Ví dụ:
#include <boost/algorithm/cxx11/copy_if.hpp>
#include <boost/assign/list_of.hpp> // for 'list_of()'
#include <boost/foreach.hpp>
#include <iostream>
#include <vector>
#include <iterator>
struct Odd
{
bool operator()(int n)
{
return n & 1;
}
};
int main()
{
std::vector<int> v = boost::assign::list_of(0)(1)(2)(3)(4);
BOOST_FOREACH(int i, v)
std::cout << i << ' ' ;
std::vector<int> out;
boost::algorithm::copy_if(v.begin(), v.end(), std::back_inserter(out), Odd());
std::cout << std::endl;
BOOST_FOREACH(int i, out)
std::cout << i << ' ' ;
}
Đầu ra:
0 1 2 3 4
1 3
- 1. Tại sao không có toán tử [] cho danh sách std ::?
- 2. Tại sao không có std :: stou?
- 3. Tại sao không std :: pair có iterators?
- 4. Thuật toán sao không có chuyển động chéo
- 5. Tại sao thuật toán Dijkstra sử dụng phím giảm? thuật toán
- 6. Thuật toán "sắp xếp nhị phân" có tồn tại không?
- 7. Tại sao thuật toán xáo trộn này sai?
- 8. Tại sao thuật toán haskell đơn giản này lại chậm?
- 9. thuật toán sao chép với ifstream
- 10. Tại sao không có chuyên môn :: shared_ptr <T[]>?
- 11. Thuật toán này có tuyến tính không?
- 12. Thuật toán giống như sao chép với bốn vòng lặp
- 13. Tôi có thể sao chép các phần tử 'vector' trong 'bộ' bằng thuật toán sao chép không?
- 14. Sử dụng thuật toán nào: Thuật toán băm được quản lý và không được quản lý
- 15. Tại sao `std :: string` lại có hàm` find` thành viên?
- 16. Truyền tham số biến đổi thuật toán std theo giá trị so với tham chiếu
- 17. Tại sao std :: for_each hoạt động chuỗi không sửa đổi?
- 18. Tại sao std :: mảng < T, 0 > không trống?
- 19. Tại sao std :: packaged_task <void()> không hợp lệ?
- 20. tại sao for_each hoạt động mà không cần std :: prefix
- 21. Xóa một std :: vector cần một toán tử gán. Tại sao?
- 22. Có những thuật toán đã biết của thuật toán tính toán sai số màu CIEDE2000 hoặc CIE94 Delta-E không?
- 23. Tại sao tôi nhận được thuật toán "thuật toán không hội tụ" và "được trang bị prob số 0 hoặc 1" với cảnh báo glm?
- 24. Tại sao khóa một std :: mutex không chặn thread
- 25. Tại sao toán tử ++ trả về giá trị không const?
- 26. std :: back_inserter cần const_reference trên GCC cũ hơn. Tại sao?
- 27. Thuật toán Khác biệt
- 28. Tại sao tôi không thể xóa chuỗi khỏi std :: set with std :: remove_if?
- 29. Tại sao std :: hash không được định nghĩa cho std :: weak_ptr trong C++ 0x?
- 30. Thuật toán kỹ thuật Facebook Bigpipe
+1 Tôi chưa bao giờ nghĩ về nó. – AraK
Nó sẽ được thêm vào tiêu chuẩn tiếp theo. Dự thảo hiện tại có nó trong chương 25.2.1 trong thư viện thuật toán. –
Trùng lặp: http://stackoverflow.com/questions/794320/are-they-adding-copyif-to-c0x –