0

I'm not too familiar with exception handling so could someone help me with this problem?? So for this program, incase of a non-existing key in the std::map, I want to throw something but I dont know what.

the map key if it exists will be a phone number (string), but if it doesn't exist what would it be??

class SmartCarrier{
private:
    string carrier_name_;
    map<string,vector<Message*>> accounts_map;
public:
    Search();
}

void phone::Search{

    string phone_number;


    map<string,vector<Message*>>::iterator iter;


    cout << "Enter a phone number: ";
    getline(cin,phone_number);

try{
    iter = phone_map.find(phone_number);

    if (iter ==phone_map.end()) {
        //Incase of a non-existing phone number what do I throw? 
        throw iter;
    }

}
catch(/*iter ??? what should the block catch as a value?*/){
   cout << "Phone number not found." << endl;
}
  • What is the type of `iter`? That's what you need to catch. Not that it really matter in your case, since it will always be equal to `phone_map.end()`. I suggest you use [one of the standard exception classes](http://en.cppreference.com/w/cpp/error), perhaps making up your own based on a standard class. – Some programmer dude Dec 09 '16 at 07:47
  • Also for your information: While using exceptions have a negligible impact on performance if no exceptions are thrown, exceptions in C++ do have a sizeable impact on performance if you throw and catch one. Exceptions should only be used in *exceptional* cases. Failure to validate user input is usually not such an exceptional case. – Some programmer dude Dec 09 '16 at 07:51
  • I think this is a bad example of exception handling. You don't need try-catch block here at all. – Anton Shmelev Dec 09 '16 at 07:52
  • What if I have fat fingers and type in a bad phone number? You're going to throw an exception for that situation? Humans typing in something wrong is *not* an exceptional case, as the previous comment pointed out. – PaulMcKenzie Dec 09 '16 at 07:56
  • Although this could be done in a much simpler way the specs for my assignment tell me to do so. I guess my professor wants me to get used to exception handling. I honestly dont know when to use it and what "exceptional cases" refers to in this context. – Person_Object Dec 09 '16 at 08:11
  • An example of an exceptional case is one where the preconditions **must** be met, else there is something seriously wrong. A person typing something wrong is not one of those situations, it's simple user error and just ask to re-enter the information. On the other hand, a data file generated from an outside source that should **never** be blank is discovered to be blank -- throw an exception. Out of memory, or access the first item in an empty queue -- throw an exception. Your professor is probably a Java programmer, where in Java throwing exceptions seems to be the norm for any error. – PaulMcKenzie Dec 09 '16 at 12:30

2 Answers2

1

Rule of thumb - you always throw a derived class of std::exception, if not stated otherwise by some style guide. You can use already defined common exceptions, like std::runtime_error. And pass error data as exception argument, that's the whole point of exceptions - propagate the error data.

And always catch by const-reference.

In your case you might simply do:

try {
    auto iter = phone_map.find(phone_number);
    if (iter == phone_map.end()) {
        throw std::runtime_error{ "Incorrect phone number" };
    }
} catch(const std::exception& e){
    cout << e.what() << endl;
}

In your case you can throw an iterator, and catch like this:

try {
    throw phone_map.end();
} catch (const map<string,vector<Message*>>::iterator& e) {
    // Do Something
}

But this is not recommended.

Starl1ght
  • 4,422
  • 1
  • 21
  • 49
0

I'd say that in this particular situation you don't need to throw any exceptions. The Search name of the function, from the reader standpoint, probably means that the only responsibility of the function is to check whether or not there's a such element in the map. Returning value by an exception is a very strange (and inefficient) way. Here I would use std::map::count - it returns 1 if such value is in the map, and 0 otherwise.

If you really need to throw an exception in case of abscence of value, look at std::map::at(). It throws an std::out_of_range exception if the key is not present.

For more info on std::map::at() and other methods of retrieval information from std::map please see this.

Community
  • 1
  • 1
alexeykuzmin0
  • 6,344
  • 2
  • 28
  • 51