42 votes

Équivalent en C++ de Yield en C# ?

public void Consumer()
{
    foreach(int i in Integers())
    {
        Console.WriteLine(i.ToString());
    }
}

public IEnumerable<int> Integers()
{
    yield return 1;
    yield return 2;
    yield return 4;
    yield return 8;
    yield return 16;
    yield return 16777216;
}

Existe-t-il un moyen avec une astuce de template (ou autre) pour obtenir la même syntaxe en c++ ?

29voto

Łukasz Milewski Points 1401

Jetez un œil à boost::Coroutine. Il fait ce que vous voulez. http://www.crystalclearsoftware.com/soc/coroutine/index.html#coroutine.intro

Exemple du tutoriel

http://www.crystalclearsoftware.com/soc/coroutine/coroutine/tutorial.html

 int range_generator(generator_type::self& self, int min, int max) 
 {
   while(min < max)
     self.yield(min++);
   self.exit();
 }

11voto

Feng Wang Points 91

En C++14, vous pouvez imiter yield cette façon :

 auto&& function = []() { 
    int i = 0; 
    return [=]() mutable { 
        int arr[] = {1,2,4,8,16,16777216}; 
        if ( i < 6 ) 
            return arr[i++]; 
        return 0; 
    }; 
}();

Un exemple en direct est disponible sur http://ideone.com/SQZ1qZ

3voto

Michael IV Points 3266

Voici la version ASM "roll your own" : http://www.flipcode.com/archives/Yield_in_C.shtml

 #include <stdio.h
#include <conio.h
#include <iostream.h


//
// marks a location in the program for resume
// does not return control, exits function from inside macro
//
// yield( x, ret )
//      x : the 'name' of the yield, cannot be ambiguous in the
//          function namespace
//    ret : the return value for when yield() exits the function;

//          must match function return type (leave blank for no return type)

#define yield(x,ret)                            \
    {                                           \
        /* store the resume location */         \
        __asm {                                 \
            mov _myStaticMkr,offset label_##x   \
        }                                       \
                                                \
        /* return the supplied value */         \
        return ret;                             \
    }                                           \
    /* our offset in the function */            \
    label_##x:



//
// resumes function from the stored offset, or
// continues without notice if there's not one
// stored
//
// resume()
//   <void

#define resume()                        \
    /* our stored offset */             \
    static _myStaticMkr=0;              \
                                        \
    /* test for no offset */            \
    if( _myStaticMkr )                  \
    {                                   \
        /* resume from offset */        \
        __asm                           \
        {                               \
            jmp _myStaticMkr            \
        }                               \
    }


// example demonstrating a function with an int return type
// using the yield() and resume() macros
//
// myFunc()
//   <void

int myFunc()
{
    resume();

    cout << "1\n";

    yield(1,1);

    cout << "2\n";

    yield(2,1);

    cout << "3\n";

    yield(3,1);

    cout << "4\n";

    return 0;
}



// main function
//
// main()
//   <void

void main( void )
{
    cout << "Yield in C++\n";
    cout << "Chris Pergrossi\n\n";

    myFunc();

    do

    {
        cout << "main()\n";
        cout.flush();
    } while( myFunc() );

    cout.flush();

    getch();
}


/*

// example demonstrating a function with no return type
// using the yield() and resume() macros
//
// myFunc()
//   <void

void myFunc()
{
    resume();

    cout << "1\n";

    yield(1);

    cout << "2\n";

    yield(2);

    cout << "3\n";

    yield(3);

    cout << "4\n";

    return;
}



// main function
//
// main()
//   <void

void main( void )
{
    cout << "Yield in C++\n";
    cout << "Chris Pergrossi\n\n";

    myFunc();

    for( int k = 0; k < 4; k ++ )
    {
        cout << "main()\n";
        cout.flush();

        myFunc();
    }

    cout.flush();

    getch();
}

*/  

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X