-1

In our recent project i write a macro that will continue on given condition and as explained here C multi-line macro: do/while(0) vs scope block I tried to use do--while to achieve that. Below is sample code to illustrate that :

#define PRINT_ERROR_AND_CONTINUE_IF_EMPTY(dummy,dummystream,symbol,errorString) \
  do{ \
    if(dummy.empty())\
    {\
        dummyStream<<symbol<<",Failed,"<<errorString<<std::endl;\
        continue;\
    }\
  }while(0) 
int main()
{
  int x =9;    
  std::ofstream& ofsReportFile;
  while(x>5)
  {
      std::string str;
      PRINT_ERROR_AND_CONTINUE_IF_EMPTY(str,ofsReportFile,"Test","Test String is Empty");
      std::cout<<x<<std::endl;
      x--;
  }
  return 0;
}

However this is not working as expected and the reason may be continue statement inside do while so question how to write multi-line macro with continue statement and also user of that macro can call it like CONTINUE_IF_EMPTY(str);

Community
  • 1
  • 1
PapaDiHatti
  • 1,841
  • 19
  • 26

1 Answers1

1

How about a lambda? This looks like a good replacement for that macro that is both global (as all macros are) and oddly specific. Plus, you get captures to help whittling down the repeated parameters.

int main()
{
    int x = 9;
    std::ofstream& ofsReportFile = /* ... */;

    auto const reportEmpty = [&](std::string const &str) {
        if(str.empty()) {
            ofsReportFile << "Test, Failed, Test String is Empty" << std::endl;
            return true;
        }
        return false;
    };

    while(x > 5)
    {
        std::string str;

        if(reportEmpty(str))
            continue;

        std::cout << x << std::endl;
        x--;
    }
}
Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Any reason not to use a function instead of a lambda? I'm not saying it's wrong, it's just by my experience a lambda requires more thought process than a regular function (because I for instance have to scan the local function for the `reportEmpty` name instead of via functions etc). A lambda, for me, is more something you use when you need the caller to tell the callee what kind of logic to use (for instance when using find for a specific property on an object). This, to me, would be fine to refactor to a function instead of a lambda. – default Mar 29 '17 at 12:23
  • 1
    @Default I'm taking advantage of the capture list to avoid passing in the output stream at every call. Apart from that, you're right that it could be extracted into a function -- but we don't know frop OP whether this functionality is used/usable elsewhere. If it is, then the best solution is a higher-order function: `auto makeEmptyReporter(std::ofstream &s) { return [&s](std::string const &str) { /* ... */ }; }` – Quentin Mar 29 '17 at 12:27