Salve,
grazie mille per la risposta.
Tuttavia credo che la frase che lei ha citato si riferisse al fatto che se un catch ha come argomento un array di un certo tipo può ricevere eccezioni che sono puntatori a quel tipo, e che se un catch ha come argomento una funzione può ricevere eccezioni che sono puntatori a funzione (esattamente come accade nella dichiarazione di una funzione).
Come ad esempio accade in
#include <iostream>
int main () {
void (*p)();
try{throw p;}
catch(void ()){std :: cout << "ciao, sono il catch(void ())!" << '\n';}
int *l;
try{throw l;}
catch(int[ ]) {std :: cout << "ciao, sono il catch(int [ ])!" << '\n';}
}
Riguardandomi per bene l'argomento credo di aver trovato la risposta, che riporto qualora servisse a qualcun altro.
http://en.cppreference.com/w/cpp/language/thro
First, copy-initializes the exception object from expression (this may call the move constructor for rvalue expression, and the copy/move may be subject to copy elision), then transfers control to the exception handler with the matching type...
Il fatto di ricevere un'eccezione come riferimento non evita il fatto che venga fatta una copia nel momento del throw; il passaggio per riferimento nel catch è efficace nel momento in cui in un catch viene inserito
throw;
a questo punto l'eccezione viene rilanciata nel livello di stack superiore e qualora trovasse un catch adatto che riceva l'eccezione per riferimento riceverebbe l'eccezione senza che venga fatta alcuna copia.
Ad esempio nel seguente codice
#include <iostream>
int (*ptr)() = nullptr;
int funz() {std::cout << "funz\n"; return 1;}
void gunz(){try{throw ptr;}
catch(int (*&l)()){l = funz; throw;}
}
int main()
{
try{gunz();}
catch(int (*&po)()) {
po();
}
}
l'inizializzazione che l subisce nel catch di gunz arriva al catch di main visto che l'eccezione è stata rilanciata e ricevuta per riferimento. Infatti l'espressione
po();
non genera segmentation fault. In tutto ciò ptr rimane non inizializzato.