Bug del compilatore con il parametro template = void* - pagina 7

 
Alexey Navoykov:

Io avrei fatto così:

Trovo questo stile scomodo. Vale a dire, si tratta di "pennarelli".

 
fxsaber:

Quindi anche tu vuoi degli avvertimenti? Cos'è questo doppio standard: in entrambi i posti il comportamento è inequivocabile, ma con le parentesi siete contro gli avvertimenti e qui siete a favore?

Avete bisogno di un avvertimento per non fare errori difficili da trovare. Quindi la difficoltà è una valutazione soggettiva. Quindi con le parentesi non si fanno errori, e qui è possibile. E per me è il contrario.

Quindi a chi di noi dovrebbero essere adattate le regole per l'emissione di avvertimenti?

Sembra che tu non capisca il punto: il casting dinamico deve sempre essere un'operazione esplicita. In qualsiasi linguaggio normale, sia esso C++, C#, Java o qualsiasi altro linguaggio OOP, tale codice non verrà compilato. Questa è la base di una OOP affidabile. Ma è stato dimenticato qui per qualche motivo. Non ho pensato che il paragone con la staffa fosse appropriato in questo caso.

 
Alexey Navoykov:

La base dei fondamenti di una OOP affidabile.

La base nell'ambiguità.

 
Ilya Malev:

Non vedo il senso del codice di riferimento (anche se non uso nemmeno le librerie standard). Se mettere un oggetto in un array implica la creazione di una copia di esso, allora il metodo di assegnazione o il costruttore di copia devono essere dichiarati e descritti esplicitamente in questa classe, altrimenti nessun wrapper sarà comunque utile. Se avete solo bisogno di mettere un riferimento a un oggetto in un array, non avete bisogno di nessun wrapper (perché?).

A cosa vi serve una tale matrice? Poiché è quasi analogo a un vettore più, dovrebbe funzionare come vector<int>, vector<class_name>, vector<class_name*>. Se puoi implementarlo senza wrapping per mezzo di µl, buon per te (non credo che sia possibile). Non avete la possibilità di correre attraverso un array e chiamare i distruttori ( _data[i].~Destr() ), nessuna specializzazione parziale e nessun trucco SFINAE. Questo wrapping rende l'array adatto a puntatori a oggetti nell'heap senza rompere la possibilità di lavorare con vector<int>, per esempio.

vector<unique_ptr<my_class>> v1;

vector<my_class> v2;

vector<int> v3;

ZS: che dire, vector<nome_classe*> non funzionerà come previsto anche in plus (chiamata destructor alla fine della vita del vettore) c'è anche bisogno di wrapping.
 
pavlick_:

ZS: che dire, vector<nome_classe*> non funzionerà come previsto anche in plus (chiamata al distruttore alla fine della vita del vettore) ha bisogno anche di un wrapping.

Funzionerà? )

template<typename T>
void del(T par){printf("%s не удаляем",typename(T));}

template<typename T>
void del(T *par){printf("%s удаляем",typename(T));delete par;}

class A{public:void~A(void){printf("удаляем %i",&this);}};

void OnStart()
 {
  int var1;
  A *var2=new A;
  del(var1);
  del(var2);
 }

P.S. Per analogia, una funzione può restituire qualsiasi cosa invece di void, e non avete bisogno di nessuna SFINAE.

 
Sì, va bene. Ma abbiamo ancora bisogno di un wrapper: abbiamo bisogno di un array universale, quindi a volte ha puntatori che devono essere cancellati, e a volte no (beh, solo un insieme di puntatori - il risultato di trovare qualcosa in un altro array).
 
pavlick_:

Il lato positivo è che la cancellazione di void* è UB.

A proposito, non ci avevo nemmeno pensato prima, grazie per il suggerimento. Si scopre che delete in questo caso è simile a free(). Dovrebbe essere vietato, poiché delete è posizionato per gli oggetti e libera semplicemente la memoria aggirando le regole.

Anche se i distruttori sono chiamati anche qui, ma in caso di porting del codice in C++ si possono incontrare problemi.

 
pavlick_:
Sì, andrà bene. Ma abbiamo ancora bisogno del wrapping: dopotutto abbiamo bisogno di un array universale, quindi a volte ha dei puntatori che devono essere cancellati, e a volte no (beh, solo un mucchio di puntatori - il risultato della ricerca di qualcosa in un altro array).

Beh, nessuno vieta di passare un'opzione aggiuntiva quando si crea un array - se cancellare gli elementi quando lo si cancella o no, e renderlo on o off per default (a vostro piacimento). Dopotutto, non si può mai indovinare se si vogliono cancellare degli oggetti o no)).

P.S. A proposito, avvolgere un puntatore prima di metterlo in un array non risolve la questione della necessità o meno di cancellare il suo oggetto base quando si cancella l'array))
 
fxsaber:

Le parentesi aggiuntive hanno eliminato completamente l'influenza delle priorità linguistiche. Tutto diventa completamente privo di ambiguità. Questo rende affidabile al 100% che nulla si romperà dopo la prossima build.

Con questo in mente, riassumo:


A100
Sviluppatori
fxsaber
staffe
solo in luoghi dove sono indispensabili
forse anche in posti dove MQL4 era diverso prima
sono necessari ovunque
avvertimenti inutili
non necessario
solo in luoghi dove MQL4 era diverso prima
necessario ovunque
priorità
è richiesto
richiesto
non necessario in linea di principio (perché le parentesi li sostituiscono)

Se non l'ho detto correttamente - per favore correggetemi - ho reso il mio concetto breve e non ambiguo dove sono necessari avvertimenti sulle parentesi

 
Ilya Malev:

Beh, nessuno vieta di passare un'opzione aggiuntiva quando si crea un array - se cancellare gli elementi quando lo si cancella o no, e renderlo on o off di default (a vostro piacimento). Perché è difficile da indovinare, dovrebbe cancellare gli oggetti o no)).

In generale, sì, si può fare così.

P.S. A proposito, solo perché si avvolge un puntatore prima di metterlo in un array, la questione se è necessario cancellare il suo oggetto base o no quando si cancella l'array non sarà più chiara))


Se non lo incarti, non lo cancelli, se lo incarti, lo cancelli, è chiarissimo.

ZS: ma se lo facessi, farei il più simile possibile alla libreria standard plus (nomi, comportamento, ecc.), quindi non ho scelta. Perché preoccuparsi di creare un'altra specifica quando tutto è già scritto?