2009-09-07 11 views

답변

5

정말로 할 수는 없지만 위조 할 수는 있습니다. 여기에 a way you can fake it in C이 있는데, C++에서도 사용할 수 있습니다.

+1

정확히 "말하고 싶다"와 "구현하는 것"사이에는 아무런 차이가 없지만 정확히 말하려고했던 +1입니다. 나는 C++에서 functor의 멤버 변수에서 코 루틴 상태를 원하고, 전역을 사용하고 anakin과 같이 명명 된 함수를 호출하는 대신 다른 인스턴스로 호출 할 수 있다고 생각합니다. 추가 매개 변수를 사용하여 C에서 유사한 작업을 수행 할 수는 있지만 원하는 작업은 거의 없습니다. –

1

여러 차례 코 루틴을 호출하고 다른 답변을 얻으면 어떤 상태가 유지된다는 것을 의미합니다. 상태를 유지하는 방법은 객체입니다. 함수 호출처럼 보이게 만드는 방법은 연산자 오버로딩입니다. http://en.wikipedia.org/wiki/Function_object을 참조하십시오.

11

C++에는 'iterators'가 있습니다. 하나는 명시 적으로 중개자를 요구하고, 명시 적으로 증가시키고 그것을 역 참조합니다.

표준 라이브러리 함수와 함께 사용하려면 대부분 std::forward_iterator에서 파생되어야하며 함수의 수를 구현해야합니다.

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()); 
5

반복자에 정교 :

컬렉션에 쌓는 발전기를 모방하려는 다른 방법은 모두 그 함수 값의 피드 멤버 함수 (수율)에 인자로서의 기능을 허용한다 구현 : 이것은 예입니다. 루프 변수 또는 표준 알고리즘으로 사용할 수 있습니다.

#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; 
} 
+0

'TGenerator' 생성자의 세 번째 매개 변수는'T step' 대신에'TDiff step'이어야합니다. – vvnurmi

+0

감사! 그것을 수정했습니다. – xtofl

1

당신은 boost.context을 (죄송합니다,하지 부스트 분포하지만, 당신이 boost vault에서 그것을 얻을해야합니다)를 사용할 수 있습니다. 이것은 ... 여러분은 ... 순수한 BLACK MAGIC입니다

#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); 
} 
8

:

http://www.codeproject.com/Articles/29524/Generators-in-C

나는 그것을 시도했습니다, 그리고

전형적인 예제 코드는 다음과 같이 될 것이다 재귀 적으로도 작동합니다. 나는 그 이후로 정기적으로 사용 해왔다. C + +에서 1 등 시민으로 거의 발전기. 성능 오버 헤드가 없습니다.

필자와 가장 깊은 관계에서 곧

+1

그것은 흑 마술이 아닙니다 ... 그러나 그것은 매우 un-C++ 11-ish입니다. – einpoklum

관련 문제