Esta questão veio à minha mente, quando eu tinha algo como
enum Folders {FA, FB, FC};
e queria criar uma matriz de contêineres para cada pasta:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
(Usar mapas é muito mais elegante de usar: std::map<Folders, ContainerClass*> m_containers;
:)
Mas, voltando à minha pergunta original: e se eu não quiser codificar o tamanho do array, há uma maneira de descobrir quantos itens estão nas pastas? (Sem depender de, por exemplo, FC
ser o último item da lista o que permitiria algo como ContainerClass*m_containers[FC+1]
se não estou enganado.)
c++
count
enumeration
Fuenfundachtzig
fonte
fonte
int(FA) | int(FB) | int (FC)
também é um valor legal para umaFolders
variável. Se você estiver dimensionando dem_containers
forma que qualquerFolders
variável seja um índice válido,[FC+1]
não seria grande o suficiente.Respostas:
Não há realmente uma boa maneira de fazer isso, geralmente você vê um item extra no enum, ou seja,
Então você pode fazer:
Ainda não é muito bom.
Mas é claro que você percebe que apenas o número de itens em um enum não é seguro, dado, por exemplo,
o número de itens seria 4, mas os valores inteiros dos valores enum estariam fora do intervalo do índice da matriz. Usar valores enum para indexação de array não é seguro, você deve considerar outras opções.
editar: conforme solicitado, fez a entrada especial destacar-se mais.
fonte
Para C ++, existem várias técnicas de enum de tipo seguro disponíveis, e algumas delas (como o Boost.Enum proposto-mas-nunca-enviado ) incluem suporte para obter o tamanho de um enum.
A abordagem mais simples, que funciona tanto em C quanto em C ++, é adotar uma convenção de declarar um valor ... MAX para cada um de seus tipos de enum:
Editar : Quanto
{ FA, FB, FC, Folders_MAX = FC}
contra{FA, FB, FC, Folders_MAX]
: Eu prefiro definir o ... valor MAX para o último valor legal do enum por algumas razões:Folders_MAX
fornece o valor enum máximo possível).Folders_MAX = FC
se destaca um pouco mais das outras entradas (tornando um pouco mais difícil adicionar acidentalmente valores enum sem atualizar o valor máximo, um problema mencionado por Martin York).fonte
enum Folders { FA, FB, FC, Folders_MAX }; ContainerClass *m_containers[Folders_MAX];
:?struct SomeEnum { enum type {FA, FB, FC, NB__};};
Que tal traços, em estilo STL? Por exemplo:
escrever um
especialização (possivelmente constexpr se você usar c ++ 11). Então, em seu código de teste forneça quaisquer asserções estáticas para manter as restrições que std :: numeric_limits :: max () = last_item.
fonte
std::numeric_limits<enum Foo>::max()
sempre retorna zero ... (consulte a pergunta para obter a resposta vinculada) Testado em enums normais (enum Foo { ... }
), enumsenum class Foo : uint8_t { ... }
com dicas de tipo ( ) com gcc 5.2.0 @ Linux e MinGW 4.9.3 @ Windows.std::numeric_limits<std::underlying_type<Foo>::type>::max()
, ele retorna o valor máximo do tipo subjacente, ou seja, 0xFFFFFFFF para inteiros de 32 bits, o que não é útil neste contexto.)namespace gx { enum struct DnaNucleobase : char { A, C, G, T }; }
Então:namespace std { template<> struct numeric_limits<enum ::gx::DnaNucleobase> { typedef enum ::gx::DnaNucleobase value_type; static constexpr value_type max() { return value_type::T; } (...)
Estd::cout << std::numeric_limits<::gx::DnaNucleobase>::max() << std::endl;
imprime o resultado esperado. Testado com os sabores gcc 5.2.1 e 4.8 / 4.9.numeric_limits<T>::max()
. A única coisa que a função poderia retornar razoavelmente é o valor enumerado mais alto. Ele retornaria2
, mas o OP (neste caso específico) precisaria que ele retornasse3
. Uma vez que você tenha valores não padrão para o enum (FB = 2057
), todas as apostas estão canceladas, não é possível nem mesmo+ 1
contornar o erro off-by-one. Se houvesse umnumeric_limits<T>::number_of_elements_of_the_set()
(ou um nome mais curto), ele poderia ser usado sem ambigüidade.Adicione uma entrada, no final de seu enum, chamada Folders_MAX ou algo semelhante e use esse valor ao inicializar seus arrays.
fonte
Gosto de usar enums como argumentos para minhas funções. É um meio fácil de fornecer uma lista fixa de "opções". O problema com a resposta mais votada aqui é que, usando-a, um cliente pode especificar uma "opção inválida". Como um spin off, recomendo fazer essencialmente a mesma coisa, mas usar um int constante fora do enum para definir a contagem deles.
Não é agradável, mas é uma solução limpa se você não alterar o enum sem atualizar a constante.
fonte
Eu realmente não vejo nenhuma maneira de realmente obter o número de valores em uma enumeração em C ++. Qualquer uma das soluções antes mencionadas funciona, desde que você não defina o valor de suas enumerações se você definir seu valor que poderá se deparar com situações em que criará matrizes muito grandes ou muito pequenas
neste exemplo, o resultado criaria um array de 3 itens quando você precisa de um array de 5 itens
neste exemplo, o resultado criaria uma matriz de 301 itens quando você precisa de uma matriz de 5 itens
A melhor maneira de resolver este problema no caso geral seria iterar por meio de suas enumerações, mas isso não está no padrão até onde eu sei
fonte