if/else conditional statements have nothing to do with throw or try/catch blocks that safely handles exceptions.
try/catch:
You can throw an exception if you expect your code block/section of having any possible error/undefined/exceptional cases. Without interrupting your program control flow by abrupt errors and aborts, you safely execute your exception-possible code segment inside try block, raise an exception by throw if you already know about the characteristic of the exception that you are expecting, and then execute a catch block corresponding to exception by handling that exception. This way your program doesn't change its control flow by making abrupt jumps.

Whenever there is an exception, program control flow changes because the process will call an indirect procedure related to the exception, through a jump table called exception table, to the operating system subroutine called exception handler.
When the exception handler finishes processing, one of three things happens,depending on the type of event that caused the exception:
1.The handler returns control to the current instruction Icurr, the instructionthat was executing when the event occurred.
2.The handler returns control to Inext, the instruction that would have executednext had the exception not occurred.
3.The handler aborts the interrupted program.
if/else:
if/else are conditional statements. if checks for a condition to execute a code segment. else can extend if by executing a code segment in case if condition is false.
Solution Specific To Your Example:
int compare( int a, int b ) {
if ( a < 0 || b < 0 )
throwFunc( "received negative value" ); else {
// Perform normal task
}
}
compare( -1, 3 );
throwFunc(const std::string& e ) {
// do stuff with exception...
}
There is no guarantee that compare (-1,3); will execute or anything after confronting an unsafely handled code section would execute.