Chip
Chip

Reputation: 129

is there a better way to make this software flow

I have several functions that try and evaluate some data. Each function returns a 1 if it can successfully evaluate the data or 0 if it can not. The functions are called one after the other but execution should stop if one returns a value of 1.

Example functions look like so:

int function1(std::string &data)
{
    // do something
    if (success)
    {
        return 1;
    }
    return 0;
}

int function2(std::string &data)
{
    // do something
    if (success)
    {
        return 1;
    }
    return 0;
}
... more functions ...

How would be the clearest way to organise this flow? I know I can use if statements as such:

void doSomething(void)
{
    if (function1(data))
    {
        return;
    }
    if (function2(data))
    {
        return;
    }
    ... more if's ...
}

But this seems long winded and has a huge number of if's that need typing. Another choice I thought of is to call the next function from the return 0 of the function like so

int function1(std::string &data)
{
    // do something
    if (success)
    {
        return 1;
    }
    return function2(data);
}

int function2(std::string &data)
{
    // do something
    if (success)
    {
        return 1;
    }
    return function3(data);
}
... more functions ...

Making calling cleaner because you only need to call function1() to evaluate as far as you need to but seems to make the code harder to maintain. If another check need to be inserted into the middle of the flow, or the order of the calls changes, then all of the functions after the new one will need to be changed to account for it.

Am I missing some smart clear c++ way of achieving this kind of program flow or is one of these methods best. I am leaning towards the if method at the moment but I feel like I am missing something.

Upvotes: 0

Views: 47

Answers (2)

acegs
acegs

Reputation: 2809

I think you can make a vector of lambdas where each lambdas contains specific process on how you evaluate your data. Something like this.

std::vector<std::function<bool(std::string&)> listCheckers;

listCheckers.push_back([](std::string& p_data) -> bool { return function1(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function2(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function3(p_data); });
//...and so on...

//----------------------------- 
std::string theData = "Hello I'm a Data";

//evaluate all data
bool bSuccess = false;
for(fnChecker : listCheckers){
    if(fnChecker(theData)) {
        bSuccess = true;
        break;
    }
}

if(bSuccess ) { cout << "A function has evaluated the data successfully." << endl; }

You can modify the list however you like at runtime by: external objects, config settings from file, etc...

Upvotes: 0

Igor Tandetnik
Igor Tandetnik

Reputation: 52471

void doSomething() {
    function1(data) || function2(data) /* || ... more function calls ... */;
}

Logical-or || operator happens to have the properties you need - evaluated left to right and stops as soon as one operand is true.

Upvotes: 1

Related Questions