3

I´m currently parsing a queue of tokens: Instead of checking if the queue is empty for each subsequent pop() i´ve written a lambda throwing an exception if queue.begin() == queue.end(). I wonder if this a good, "proper" implementation or if it´s generally considered to be a bad practice to throw an exception from a lambda expression?

quiZ___
  • 109
  • 1
  • 9

3 Answers3

6

Throwing an exception from a lambda function is equivalent like throwing an exception from any other function.

Now if it's a good practice in such a context to throw an exception, in my humble opinion is not. Exceptions are meant to be used in exceptional situations (e.g., a bullet pierced your CPU) and I don't think that reaching the end of a range qualifies as such (i.e., exceptional).

101010
  • 41,839
  • 11
  • 94
  • 168
  • 1
    I agree with this--regardless of whether or not it's good practice to throw an exception from a lambda, the situation the OP describes sounds like using exceptions for control flow, which is *not* good practice. – tsleyson May 07 '16 at 19:15
  • 1
    if the queue was expected to have an item in it, and didn't; that would be exceptional. – Richard Hodges May 07 '16 at 19:15
  • But if the queue do not have an expected token, the provided data is incomplete and it seems natural to throw an exception? – quiZ___ May 07 '16 at 19:18
  • @quiZ___ short answer: yes. – 101010 May 07 '16 at 19:19
  • 1
    I think the requirement to throw the exception depends on the situation and the level of abstraction. – malintha Jun 26 '19 at 23:48
2

I think its depends on what you are trying to accomplish. I personally would leave the check for an empty queue to the function where the pop is called in. There seems to be no reason to limiting the capabilities of your queue with the exception. There might be some cases you want to handle when the queue is empty, but throwing an exception and handeling this seems to lead to bloating the code to me.

Just my preference.

user1109410
  • 61
  • 1
  • 6
1

I asked myself this question while working on one of my projects.

I agree with the answers that say it can be used but it is better to limit it only to the exceptional cases (especially since when thrown, exceptions are not cheap).

In my case I used the lambda to save a file multiple times in a process of upgrading it (the code is the same for all savings and if it fails I consider it an exception because it is not supposed to happen).

Pseudo code of my project:

void upgradeFile(/* params */){

    std::string configVersion = readCurrentConfigVersion();

    auto fSaveFileAfterUpgrade = [](/* params */){
            if(!param1.saveFile(/*params*/)){
                throw std::runtime_error("My error Message");
            }
    };

    if(configVersion == "1.0"){

        const std::string versionAfterUpgrade = "1.1";

        // UPGRADE CODE...

        fSaveFileAfterUpgrade(/* params */);

        configVersion = versionAfterUpgrade;
    }

    if(configVersion == "1.1"){
        const std::string versionAfterUpgrade = "1.1a";

        // UPGRADE CODE...

        fSaveFileAfterUpgrade(/* params */);

        configVersion = versionAfterUpgrade;
    }
}

If an exception happens in the lambda the function that call upgradeFile will handle it (I setup a try catch on it).

RandomGuy
  • 648
  • 6
  • 21