Iterate through function?

Hi

I have the following function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void applyAllOps(string origin, const string& charset)
{
    for (int i = 0; i < origin.size(); ++i)
    {
        string result = applyDelete(origin, i);
    }

    for (int i = 0; i < origin.size(); ++i)
    {
        for (int j = 0; j < charset.size(); ++j)
        {
            string result = applySubstitute(origin, i, charset[j]) ;
        }
    }

    for (int i = 0; i <= origin.size(); ++i)
    {
        for (int j = 0; j < charset.size(); ++j)
        {
            string result = applyInsert(origin, i, charset[j]) ;
        }
    }
}


I would like to obtain each "result" string above. Obviously, I could add each result to a vector<string> and return this to the calling function but I think this may be prohibitively resource intensive in my use case. Is there a way of calling such a function which returns the next result value after each call e.g.:

1
2
3
4
5
string result;
while ( applyAllOps(origin, charset, result) ) // returns false after every result value obtained
{
    // do stuff to each result
}


Thanks
Last edited on
My understanding is that you're looking for something similar to Python's or C#'s "yield" statement. This can actually be done using coroutines starting in C++20. But I haven't tried this. A page on coroutines can be found here: https://en.cppreference.com/w/cpp/language/coroutines that has an example (if your compiler even supports it, which it probably doesn't).

This can be emulated pre-C++20 by using some sort of state variable as an additional argument to the function.
But, depending on your use case, an iterator or callback might be more suitable here.

I'll show an example of a callback. I strongly suggest others reading to suggest alternatives.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Example program
#include <iostream>
#include <string>
using std::string;

string applyDelete(const string& origin, size_t index)
{
    return "test 1";   
}
string applySubstitute(const string& origin, size_t index, char ch)
{
    return "test 2";   
}
string applyInsert(const string& origin, size_t index, char ch)
{
    return "test 3";
}

void applyAllOps(const string& origin, const string& charset, void (*callback)(const std::string&))
{
    for (size_t i = 0; i < origin.size(); ++i)
    {
        callback(applyDelete(origin, i));
    }

    for (size_t i = 0; i < origin.size(); ++i)
    {
        for (size_t j = 0; j < charset.size(); ++j)
        {
            callback(applySubstitute(origin, i, charset[j]));
        }
    }

    for (size_t i = 0; i < origin.size(); ++i)
    {
        for (size_t j = 0; j < charset.size(); ++j)
        {
            callback(applyInsert(origin, i, charset[j]));
        }
    }
}

void handle_result(const std::string& result)
{
    std::cout << "Result: " << result << "!\n";
}

int main()
{
    applyAllOps("foo", "bar", handle_result);
}


PS: On line 16 of your code, is that supposed to be a <=?
Last edited on
Hello rozick1,


I would like to obtain each "result" string above.


You can not. "result" is defined inside a for loop. When the for loop reaches the closing } the local variable is destroyed and no longer available.

I am thinking what work it to pass 3 vectors by reverence. Add to them each time you get a "result". The again I do not know what you want to do with the "return values from the for loops.

Andy
I'm still surprised that more people arent excited about coroutines. They're useful for exactly this kind of problem.

Naturally the standard library does not yet support coroutines, so potential users must implement their own support libraries. Definitely makes the feature less convenient to use.
Last edited on
Topic archived. No new replies allowed.