Czy istnieje sposób określenia domyślnego konstruktora modelu enum class
?User Defined C++ 11 klasa enum Domyślny konstruktor
Używam enum class
do określenia zestawu wartości, które są dozwolone dla określonego typu danych w bibliotece: w tym przypadku jest to numer identyfikacyjny PIN GPIO Raspberry Pi. Wygląda to mniej więcej tak:
enum class PinID : int {N4 = 4, N17 = 17, /* ...etc... */ }
Chodzi o mnie w ten sposób, a nie tylko z użyciem, powiedzmy, int
jest zapewnienie, że kod jest bezpieczny: Mogę static_assert
(lub w inny sposób zapewnić w czasie kompilacji - rzeczywista zastosowana metoda nie jest dla mnie ważna) takie rzeczy, że ktoś nie popełnił błędu w pisowni (podanie 5 zamiast 4 itd.) i otrzymuję automatyczne komunikaty o błędach dla niedopasowania typów, itp.
The Problem polega na tym, że enum class
ma domyślny konstruktor, który - ze względu na kompatybilność z C enum
s, zakładam (skoro mają to samo zachowanie) - inicjuje na enum class
odpowiednik 0
. W tym przypadku nie ma wartości 0
. Oznacza to, że użytkownik składając oświadczenie/definicja jak:
PinID pid = PinID();
jest coraz wyliczający, które nie są wyraźnie określone (i nawet nie wydają się „istnieć”, gdy patrzy się na kodzie), i może prowadzić do błędów w czasie wykonywania. Oznacza to również, że techniki takie jak switch
nad wartościami jawnie zdefiniowanych enumeratorów są niemożliwe bez błędu/domyślnego przypadku - czegoś, czego chcę uniknąć, ponieważ zmusza mnie to do albo throw
lub coś w stylu zwracają boost::optional
, które są mniej podatny na analizę statyczną.
Próbowałem zdefiniować domyślny konstruktor bez skutku. Ja (rozpaczliwie) próbowałem zdefiniować funkcję, która ma nazwę enum class
, ale to (raczej nieoczekiwanie) doprowadziło do dziwnych błędów kompilatora. Chcę zachować zdolność do rzutowania enum class
do int
, z wszystkimi wylicznikami N#
odwzorowanymi na ich odpowiednie #
, więc samo "zdefiniowanie", powiedzmy, N4 = 0 jest niedopuszczalne; to jest dla prostoty i zdrowego rozsądku.
Podejrzewam, że moje pytanie jest dwojakie: czy istnieje sposób na uzyskanie statycznego bezpieczeństwa, którego używam po enum class
? Jeśli nie, jakie inne możliwości wolałbyś? Co chcę jest coś czego:
- jest domyślnym constructable
- mogą być wykonane do domyślnych skonstruować do dowolnej ważnej wartości
- zapewnia „skończony zbiór określonych” wartości zapewnianej przez
enum class
es - jest co najmniej tak bezpieczne, jak typu AN
enum class
- (korzystnie) nie obejmują polimorfizm wykonania
Powodem, dla którego chcę mieć domyślną łatwość konstrukcji, jest to, że zamierzam użyć boost::lexical_cast
, aby zmniejszyć obciążenie składniowe związane z konwersjami między wartościami enum class
, a rzeczywistymi powiązanymi string
s, które wysyłam do systemu operacyjnego (w tym przypadku sysfs); boost::lexical_cast
wymaga domyślnej możliwości konstruowania.
Błędy w moim uzasadnieniu są mile widziane - zaczynam podejrzewać, że enum class
es są właściwym obiektem dla niewłaściwej pracy, w tym przypadku; wyjaśnienie będzie oferowane, jeśli zostaniesz o to poproszony. Dziękuję za Twój czas.
Patrząc na to, wygląda w zasadzie dobrze, ale czy to zadziała? Masz definicję klasy, która zawiera instancję jako członka ... ale są statyczne. Kompilator nie wkurza się wtedy. Sprytny niedźwiedź. – FizzixNerd
@FizzixNerd Nie uruchomiłem go przez kompilator, ale powinien działać ... Myślę, że jeśli dodasz operatorów strumieniowych, powinieneś być w stanie użyć go bezpośrednio z lexical_cast, przypuszczam, że zgłoszę wyjątek, jeśli pojawi się niepoprawna wartość. – PeterSW
@PeterSW, czy mógłbyś wskazać, które elementy w standardzie C++ 11 dotyczą twojej inicjalizacji zerowej? –