ho un quadro che definisce eccezione come classe noncopyable, da cui abbiamo derivato una classe copiabile (che definisce un costruttore di copia chiamando un non-copia costruttore della classe base)Lanciare copiabile classe derivante dalla noncopyable
questo funziona sotto g ++, ma non sotto MSVC 2013.
il seguente codice riprodurre il problema:
#include <iostream>
using namespace std;
#if defined _MSC_VER
#define __PRETTY_FUNCTION__ __FUNCTION__
#endif
class u {
u(const u&) = delete;
const u& operator=(const u&) = delete;/* the library we use defines it as const u& */
public:
u() { cout << __PRETTY_FUNCTION__ << "def" << endl; }
protected:
explicit u(int i) { cout << __PRETTY_FUNCTION__ << "int: " << i << endl; }
};
class e : public u {
public:
e() { cout << __PRETTY_FUNCTION__ << "def" << endl; }
e(const e& _e) : u(1) { cout << __PRETTY_FUNCTION__ << "cpy" << endl; }
e& operator=(const e& _e) { cout << __PRETTY_FUNCTION__ << endl; return *this; }
};
int foo() {
e _e;
throw _e;
return 0;
}
int main() {
try {
foo();
} catch(const e& _e) {
cout << "in catch e" << endl;
} catch(...) {
cout << "in catch..." << endl;
}
#if defined _MSC_VER
cout << "press enter to exit" << endl;
cin.get();
#endif
return 0;
}
MSVC lamenta Error 1 error C2280: 'u::u(const u &)' : attempting to reference a deleted function
alla fine della funzione foo().
g ++ e clang entrambi compilano il codice e non usano affatto il costruttore di copie (l'oggetto e viene spostato), ma nessuno dei due verrà compilato se e
non è costruibile con la copia.
MODIFICA: ho modificato il codice per forzare una copia.
BTW, se le funzioni di copia u
non vengono eliminate (né definite, pre-C++ 11 non copiabili), MSVC non riesce nella fase di collegamento durante la ricerca u::u(const u&)
. (esterno non risolto)
C'è un difetto nel mio codice o questo errore è presente in MSVC?
Questo funziona su http://webcompiler.cloudapp.net/, quindi ho intenzione di andare con un bug MSVC che è stato corretto in MSVC 2015. –
sembra un errore msvc, non richiamare il costruttore di movimento: http: // stackoverflow.com/questions/21715468/can-i-throw-a-unique-ptr – benlong
La mia prima ipotesi sarebbe che quando si lancia un oggetto 'e', si potrebbe prenderlo come' u'. (Non come riferimento ad un 'u'.) In tal caso avresti bisogno del copy ctor di' u'. Forse gcc e clang mettono quell'invocazione di copia vicino alla clausola catch (che non esiste qui), ma MSVC potrebbe volerlo mettere dopo l'istruzione 'throw'. Non sarebbe invocato, ma il compilatore lo fa riferimento. –