Pagine    Articoli    Prodotti    Forum    Cerca  
Nickname

Password


Non sei registrato?
Registrati a GPI qui!

Puoi anche attivare un vecchio utente GPI e chiedere una nuova password.
I Team

Mappa Team
I nostri utenti

Mappa Utenti
  C++11: Strongly Typed Enums - I nuovi Enum!
Pubblicato da Dario Oliveri il 2013-05-28 21:23:23

I Vecchi enum (Parte I):

 

enum Colors { 	
	R, 
	G, 
	B,
	C, 
	M, 
	Y,
	Colors_32bit = 0xdfffffff //forza il compilatore a usare una lunghezza di 32 bit per l'enum
}; 

 

Notare l'enum "Colors_32bit", sebbene possa sembrare insensato, in realtà è un trucco utilizzatissimo in progetti cross-platform per "garantire" che l'enum abbia una dimensione fissa (utile se ad esempio voglio salvare il valore dell'enum su file).

 

Inoltre un altro problema degli enum è sempre stato la mancanza di uno "scope", questo ha diffuso varie pratiche bizzarre tutte con un solo traguardo: evitare i conflitti di nomi

 

Vediamo le soluzioni che altre persone hanno inventato "ad-hoc".

 

I Vecchi Enum (Parte II):

// Solo C++

namespace Colors{  //utile negli IDE per far comparire tutti i colori  digitando "Colors::"
	enum ENUM{	
		R,
		G,
		B,
		C,
		M,
		Y
	};

}

// C / C++

struct Colors{   // Meno utilizzato, anche qui negli IDE basta digitare "Colors::"
	enum{	
		R,
		G,
		B,
		C,
		M,
		Y
	} ENUM;
};

// Naming conventions

// Utilizzatissimo (secondo me molto macchinoso soprattutto per gli utenti finali).
// Se sappiamo che l'enum è "ColorTypes" prendiamo le iniziali "CT" e ci aggiungiamo "E" (che sta per Enum) davanti
// digitanto "ECT" nell'IDE otteniamo la lista di quello che ci serve
enum ColorsType{
	ECT_Red,
	ECT_Green,
	ECT_Blue,
	ECT_Cyan,
	ECT_Magenta,
	ECT_Yellow
}

 

 

Utilizzare gli enum in questo modo può sembrare bizzarro, ma era l'unico modo di evitare conflitti di nomi (simile nella logica ai prefissi delle funzioni C).

 

In C++11 finalmente tutti questi problemi vengono risolti fornendo un tipo forte e formale (fino ad un certo punto, sono validi soltanto tipi "interi": char, unsigned etc.. ).

 

#include  < cstdint >

enum struct Colors: std::int16_t{
    R,
    G,
    B,
    C,
    M,
    Y
};

 

 

Utilizzando tipi di lunghezza nota non ci saranno più problemi riguardo alla lunghezza in bytes, questo permette di gestire più facilmente codice in progetti cross-platform.

 

 

Altri vantaggi:

Ora gli enum sono "forward declarable", significa che possiamo dichiarali e solo in un secondo momento possiamo definirli

 

#include < cstdint >

enum struct Colors:char; //Dobbiamo comunque specificare il tipo (se non mettiamo niente è "int")

std::uint32_t getRGB(Colors c); //non sto accedendo ai singoli valori, pertanto non devo conoscerli per forza.

/...

enum struct Colors:char{
	R,
	G,
	B,
	C,
	M,
	Y,
};

 

 

 

Inoltre avendo un loro scope, non abbiamo più conflitti di nome

enum struct Colors: int{
	R,
	G,
	B,
	C,
	M,
	Y
};
// Compila tranquillamente infatti abbiamo Colors::R e PrimaryColors::R
enum struct PrimaryColors: int{
	R,
	G,
	B
};

 

E per finire niente più conversione implicita

 

enum struct Colors: int{
	R,
	G,
	B
}

int main(){
	int a = Colors::R; // Errore di compilazione
	int b = static_cast < int > ( Colors::R ); // ok! (Da notare che abbiamo usato "int" perchè "Colors: int" (riga 1) )
}

 

 

 

Campagne crowfunding

Just One Line
Siamo presenti su

     
Copyright ©2016 - Manifesto - Privacy - Termini di Servizio - Community - Collaboratori - Contattaci