Czy istnieje sposób sprawdzenia w C ++ 11, czy wyliczenie jest ciągłe ?
W pełni uzasadnione jest podawanie wartości wyliczeniowych, które nie są. Czy w C ++ 14, C ++ 17 jest jakaś cecha typu, a może C ++ 20, aby sprawdzić, czy wyliczanie jest ciągłe? Należy tego użyć w static_assert.
Oto mały przykład:
enum class Types_Discontinuous {
A = 10,
B = 1,
C = 100
};
enum class Types_Continuous {
A = 0,
B = 1,
C = 2
};
static_assert(SOME_TEST<Types_Discontinuous>::value, "Enum should be continuous"); // Fails
static_assert(SOME_TEST<Types_Continuous>::value, "Enum should be continuous"); // Passes
enum
. Niestety mam dzienną pracę, więc nie mogę spróbować tego napisać, chociaż głosuję za odpowiedzią w oparciu o to podejście. Jestem prawie pewien, że ktoś taki jak @barry lub @sehe mógłby to zrobić.static_assert
)? Nawet jeśli nie możesz stworzyć „pięknego rozwiązania”, napisz odpowiedź, ponieważ jestem bardzo ciekawy, jak można to zrobić w sposób ogólny.Odpowiedzi:
Przez kilka
enum
sekund możesz prawdopodobnie przebić się przez to za pomocą biblioteki Magic Enum . Na przykład:Zauważ, że jest to rzeczywiście, jak sugeruje nazwa biblioteki, „magia” - biblioteka działa na wielu hackach specyficznych dla kompilatora. W związku z tym tak naprawdę nie spełnia twoich wymagań dotyczących „czystego C ++”, ale prawdopodobnie jest tak dobry, jak to tylko możliwe, dopóki nie będziemy mieli możliwości refleksji w języku.
źródło
Nie jest to możliwe w czystym C ++, ponieważ nie ma sposobu, aby wyliczyć wartości wyliczeniowe lub odkryć liczbę wartości oraz wartości minimalne i maksymalne. Ale możesz spróbować skorzystać z pomocy swojego kompilatora, aby zaimplementować coś blisko tego, co chcesz. Na przykład w gcc można wymusić błąd kompilacji, jeśli
switch
instrukcja nie obsługuje wszystkich wartości wyliczenia:Oczywiście jest to wyspecjalizowane dla danego wyliczenia, ale definiowanie takich funkcji można zautomatyzować za pomocą preprocesora.
źródło
Chciałbym zobaczyć odpowiedź na to pytanie. Ja też tego potrzebowałem.
Niestety nie sądzę, że jest to możliwe przy użyciu istniejących narzędzi. Jeśli chcesz zaimplementować na nim cechę typu, potrzebujesz wsparcia ze strony kompilatora, więc napisanie szablonu dla niego nie wydaje się wykonalne.
Już rozszerzyłem wyliczenie o określony znacznik, aby wskazać, że jest ciągły i od razu daje ci rozmiar: konstruktor klasy enum c ++, jak przekazać określoną wartość?
Możesz też napisać własną cechę:
Musi to być wyspecjalizowane za każdym razem, gdy definiujesz ciągły wyliczenie, w którym chcesz go użyć. Niestety wymaga to konserwacji i uwagi, jeśli wyliczenie ulegnie zmianie.
źródło
Wszystkie wyliczenia są ciągłe. 0 jest zawsze dozwolone; najwyższa dozwolona wartość to najwyższy numerator zaokrąglony w górę do następnego
1<<N -1
(wszystkie bity jeden), a wszystkie wartości pomiędzy nimi są również dozwolone. ([dcl.enum] 9.7.1 / 5). Jeśli zdefiniowano ujemne elementy wyliczające, najniższa dozwolona wartość jest podobnie zdefiniowana przez zaokrąglenie w dół najniższego elementu wyliczającego.Liczniki zdefiniowane w
enum
wyrażeniach są stałymi wyrażeniami o wartości w zakresie i poprawnym typie, ale można zdefiniować dodatkowe stałe poza tymi,enum
które mają te same właściwości:constexpr enum class Types_Discontinuous = static_cast<Types_Discontinuous>(2)
źródło