Existe uma maneira de verificar no C ++ 11 se uma enumeração é contínua ?
É totalmente válido fornecer valores de enumeração que não são. Existe talvez um recurso como um traço de tipo em C ++ 14, C ++ 17 ou C ++ 20 para verificar se o enum é contínuo? Isso deve ser usado em um static_assert.
Um pequeno exemplo a seguir:
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
. Infelizmente, eu tenho um emprego diário, por isso não posso tentar escrever isso, apesar de aprovar uma resposta com base nessa abordagem. Tenho certeza de que alguém como @barry ou @sehe poderia fazê-lo.static_assert
)? Mesmo que você não consiga criar uma "solução bonita", escreva uma resposta de qualquer maneira, pois estou muito curioso para saber como isso pode ser feito de maneira genérica.Respostas:
Para vários
enum
s, você provavelmente pode abrir caminho usando a biblioteca Magic Enum . Por exemplo:Observe que isso é realmente, como o nome da biblioteca implica, "magic" - a biblioteca funciona em vários hacks específicos do compilador. Como tal, ele realmente não atende aos seus requisitos de "C ++ puro", mas provavelmente é o melhor possível, até termos instalações de reflexão na linguagem.
fonte
Isso não é possível no C ++ puro, porque não há como enumerar os valores da enumeração ou descobrir o número dos valores e os valores mínimo e máximo. Mas você pode tentar usar a ajuda do seu compilador para implementar algo parecido com o que você deseja. Por exemplo, no gcc, é possível aplicar um erro de compilação se uma
switch
instrução não manipular todos os valores de uma enumeração:Obviamente, isso é especializado para um determinado enum, mas a definição de tais funções pode ser automatizada com o pré-processador.
fonte
Eu adoraria ver uma resposta sobre isso. Eu também preciso disso.
Infelizmente, acho que isso não é possível usando os utilitários existentes. Se você deseja implementar uma característica de tipo, precisa do suporte do seu compilador, portanto, escrever um modelo para ele não parece viável.
Eu já estendi a enumeração com uma tag específica para indicar que é contínua e imediatamente fornece o tamanho: construtor de classe enum c ++, como passar um valor específico?
Como alternativa, você pode escrever sua própria característica:
Isso precisa ser especializado sempre que você define uma enumeração contígua na qual deseja usá-la. Infelizmente, isso requer alguma manutenção e atenção se o enum for alterado.
fonte
Todos os enum são contínuos. 0 é sempre permitido; o maior valor permitido é o maior enumerador arredondado para o próximo
1<<N -1
(todos os bits um) e todos os valores intermediários também são permitidos. ([dcl.enum] 9.7.1 / 5). Se houver enumeradores negativos definidos, o valor mais baixo permitido é definido da mesma forma, arredondando para baixo o enumerador mais baixo.Os enumeradores definidos em
enum
são expressões constantes com um valor no intervalo e o tipo correto, mas você pode definir constantes adicionais fora dasenum
quais têm as mesmas propriedades:constexpr enum class Types_Discontinuous = static_cast<Types_Discontinuous>(2)
fonte