Tôi muốn biết cách triển khai trình tạo, như Python, trong C++? Python có thể sử dụng từ khóa "yield" để làm như vậy. Nhưng làm thế nào để làm điều đó trong C + +?Làm cách nào để triển khai trình tạo trong C++?
Trả lời
Bạn không thể làm điều đó, thực sự, nhưng bạn có thể giả mạo nó. Đây là a way you can fake it in C, bạn cũng có thể sử dụng trong C++.
+1 chính xác những gì tôi định nói, mặc dù không có sự khác biệt nào giữa "giả mạo" và "triển khai". Tôi nghi ngờ rằng trong C++ bạn có thể muốn trạng thái coroutine trong các biến thành viên của một functor, và gọi nó, với các trường hợp khác nhau khi thích hợp, thay vì sử dụng globals và gọi một hàm có tên là anakin. Bạn có thể làm một điều tương tự trong C với một tham số bổ sung, nhưng ít có khả năng muốn. –
Gọi một coroutine nhiều lần và nhận các câu trả lời khác nhau có nghĩa là bạn giữ một số trạng thái. Cách giữ trạng thái là đối tượng. Cách làm cho chúng trông giống như gọi hàm là toán tử quá tải. Xem http://en.wikipedia.org/wiki/Function_object.
Trong C++, chúng tôi có 'trình lặp'. Một yêu cầu rõ ràng cho một interator, rõ ràng increments nó và dereferences nó.
Nếu bạn muốn chúng được sử dụng với các chức năng thư viện chuẩn, chúng chủ yếu được lấy từ std::forward_iterator
và triển khai một số chức năng của nó.
Một cách khác để bắt chước kindof một máy phát điện trên một bộ sưu tập được cho phép một hàm như là đối số để một hàm thành viên đó nguồn cấp dữ liệu (sản lượng) tất cả của nó giá trị là chức năng mà:
struct MyCollection {
int values[30];
template< typename F >
void generate(F& yield_function) const {
int* end = values+30; // make this better in your own code :)
for(auto i: values) yield_function(*i);
}
};
// usage:
c.generate([](int i){ std::cout << i << std::endl; });
// or pre-C++11:
struct MyFunction {
void operator() (int i)const { printf("%d\n", i); }
};
MyCollection c;
c.generate(MyFunction());
Để xây dựng trên các iterator thực hiện: đây là một ví dụ. Nó có thể được sử dụng như một biến vòng lặp, hoặc trong các thuật toán std.
#include <iterator>
template< typename T, typename TDiff = T >
struct TGenerator : public std::iterator<std::forward_iterator_tag,T,TDiff> {
T from,to;
T value;
TDiff step;
bool issentinel;
TGenerator(T from, T to, TDiff step, bool sentinel = false)
: from(from),to(to),step(step),issentinel(sentinel), value(from)
{}
void operator++(){ value += step; }
const T& operator*()const { return value; }
bool operator!=(const TGenerator& other) const {
return value<to;
}
TGenerator sentinel()const { return TGenerator(0,0,0,true); }
};
#include <algorithm>
#include <iostream>
int main()
{
TGenerator<int> i(0,10,3);
std::copy(i, i.sentinel(), std::ostream_iterator<int>(std::cout, " "));
return 0;
}
bạn có thể sử dụng boost.context (xin lỗi, không phải trên phân phối tăng nào, bạn sẽ có để có được nó từ boost vault).
Một mã ví dụ điển hình sẽ là như thế này:
#include <iostream>
#include <boost/context.hpp>
using namespace std;
struct Parameters {
int par1;
float par2;
};
boost::context c1;
boost::context c2;
void F(void* parameters) {
Parameters& pars = *(Parameters*)parameters;
cout << pars.par1 << endl;
c2.jump_to(c1);
cout << pars.par2 << endl;
};
int main() {
c1 = boost::context::current();
Parameters p;
p.par1 = 8;
c2 = boost::context::create_context(F , c1 , p);
c1.jump_to(c2);
p.par2 = 1.3;
c1.jump_to(c2);
}
này ... Gentlemen ... được tinh khiết ma thuật đen:
http://www.codeproject.com/Articles/29524/Generators-in-C
Tôi đã thử nó, và nó thậm chí hoạt động đệ quy. Tôi đã sử dụng nó thường xuyên kể từ đó. Máy phát điện, gần như là công dân hạng nhất trong C++. Thậm chí không có bất kỳ chi phí hiệu suất nào.
Với sự tôn trọng sâu sắc nhất của tôi đối với tác giả
Nó không phải là ma thuật đen _that_ ... tuy nhiên, nó là rất un-C++ 11-ish. – einpoklum
- 1. Làm cách nào để triển khai gọi lại trong C++?
- 2. Làm cách nào để triển khai bộ?
- 3. Làm cách nào để triển khai jScroll?
- 4. Làm cách nào để triển khai FileTimeToSystemTime?
- 5. Trình biên dịch C xác nhận - cách triển khai?
- 6. Làm cách nào để triển khai IEnumerable?
- 7. Làm cách nào để triển khai SlideShow trong Android?
- 8. Làm cách nào để triển khai tiếp tục?
- 9. Làm cách nào để triển khai các tham chiếu chuyển tiếp trong trình biên dịch?
- 10. cách triển khai Giao diện trong C++?
- 11. Việc triển khai chương trình nào là dễ nhất để nhúng vào chương trình C/C++?
- 12. Làm cách nào để triển khai `cat` trong Haskell?
- 13. Làm cách nào để triển khai mảng bit trong C/Objective C
- 14. Làm cách nào để triển khai thẻ bài trong Mongo?
- 15. Trình biên dịch phổ biến cách độc lập để triển khai macro UNUSED trong C/C++
- 16. làm cách nào để tạo rvm tạo gemset tại triển khai capistrano?
- 17. Làm cách nào để triển khai API RESTful trong Perl?
- 18. Triển khai RAII trong C#
- 19. Làm cách nào để triển khai thẻ trong Symfony 2?
- 20. Làm cách nào để triển khai gọi lại trong PHP?
- 21. Làm cách nào để triển khai OpenID trong Java
- 22. Làm cách nào để triển khai giao diện trong Ada?
- 23. Làm cách nào để triển khai Unix grep trong Perl?
- 24. Làm cách nào để __slots__ được triển khai bằng Python?
- 25. Làm cách nào để triển khai chỉ các mô-đun phụ sử dụng triển khai maven?
- 26. Làm cách nào để triển khai cấu trúc dữ liệu DOM chung trong C++?
- 27. Làm cách nào để triển khai giao thức mạng?
- 28. Làm cách nào để triển khai đúng mã cheat?
- 29. Làm thế nào để triển khai Scrum?
- 30. Làm cách nào để triển khai Tomcat từ NetBeans?
sớm, chúng tôi sẽ có thể thêm câu trả lời với C++ 20 coroutines. – xtofl