방금 ++ 또는 + =와 같은 열거 형에서 표준 수학 연산자를 사용할 수 없다는 것을 알았습니다.
그렇다면 C ++ 열거 형의 모든 값을 반복하는 가장 좋은 방법은 무엇입니까?
답변
일반적인 방법은 다음과 같습니다.
enum Foo {
One,
Two,
Three,
Last
};
for ( int fooInt = One; fooInt != Last; fooInt++ )
{
Foo foo = static_cast<Foo>(fooInt);
// ...
}
열거 형 Last
은 반복에 의해 건너 뛰기위한 것입니다. 이 “가짜” Last
열거 형을 사용하면 새 열거 형을 추가 할 때마다 for 루프에서 종료 조건을 마지막 “실제”열거 형으로 업데이트 할 필요가 없습니다. 나중에 더 많은 열거 형을 추가하려면 마지막 전에 추가하십시오. 이 예제의 루프는 여전히 작동합니다.
물론 열거 형 값을 지정하면 다음과 같이 분류됩니다.
enum Foo {
One = 1,
Two = 9,
Three = 4,
Last
};
이것은 열거 형이 실제로 반복되지 않는다는 것을 보여줍니다. 열거 형을 처리하는 일반적인 방법은 스위치 문에서 열거 형을 사용하는 것입니다.
switch ( foo )
{
case One:
// ..
break;
case Two: // intentional fall-through
case Three:
// ..
break;
case Four:
// ..
break;
default:
assert( ! "Invalid Foo enum value" );
break;
}
실제로 열거하려면 열거 형 값을 벡터에 채우고 반복하십시오. 지정된 열거 형 값도 올바르게 처리합니다.
답변
#include <iostream>
#include <algorithm>
namespace MyEnum
{
enum Type
{
a = 100,
b = 220,
c = -1
};
static const Type All[] = { a, b, c };
}
void fun( const MyEnum::Type e )
{
std::cout << e << std::endl;
}
int main()
{
// all
for ( const auto e : MyEnum::All )
fun( e );
// some
for ( const auto e : { MyEnum::a, MyEnum::b } )
fun( e );
// all
std::for_each( std::begin( MyEnum::All ), std::end( MyEnum::All ), fun );
return 0;
}
답변
열거 형이 0으로 시작하고 증분이 항상 1 인 경우
enum enumType
{
A = 0,
B,
C,
enumTypeEnd
};
for(int i=0; i<enumTypeEnd; i++)
{
enumType eCurrent = (enumType) i;
}
그렇지 않다면 내가 유일하게 왜 같은 것을 만드는 것 같아
vector<enumType> vEnums;
항목을 추가하고 일반 반복자를 사용하십시오 ….
답변
c ++ 11을 사용하면 실제로 간단한 템플릿 화 된 사용자 정의 반복자를 작성하는 대안이 있습니다.
열거 형이 있다고 가정 해 봅시다
enum class foo {
one,
two,
three
};
이 일반 코드는 트릭을 매우 효율적으로 수행합니다-일반 헤더에 배치하면 반복해야 할 열거 형에 대해 서비스를 제공합니다.
#include <type_traits>
template < typename C, C beginVal, C endVal>
class Iterator {
typedef typename std::underlying_type<C>::type val_t;
int val;
public:
Iterator(const C & f) : val(static_cast<val_t>(f)) {}
Iterator() : val(static_cast<val_t>(beginVal)) {}
Iterator operator++() {
++val;
return *this;
}
C operator*() { return static_cast<C>(val); }
Iterator begin() { return *this; } //default ctor is good
Iterator end() {
static const Iterator endIter=++Iterator(endVal); // cache it
return endIter;
}
bool operator!=(const Iterator& i) { return val != i.val; }
};
당신은 그것을 전문화해야합니다
typedef Iterator<foo, foo::one, foo::three> fooIterator;
그런 다음 range-for를 사용하여 반복 할 수 있습니다
for (foo i : fooIterator() ) { //notice the parentheses!
do_stuff(i);
}
열거 형에 공백이 없다는 가정은 여전히 사실입니다. 열거 형 값을 저장하는 데 실제로 필요한 비트 수에 대한 가정은 없습니다 (std :: underlying_type 덕분)
답변
이 솔루션이 너무 복잡합니다.
enum NodePosition { Primary = 0, Secondary = 1, Tertiary = 2, Quaternary = 3};
const NodePosition NodePositionVector[] = { Primary, Secondary, Tertiary, Quaternary };
for (NodePosition pos : NodePositionVector) {
...
}
답변
나는 종종 그런 식으로
enum EMyEnum
{
E_First,
E_Orange = E_First,
E_Green,
E_White,
E_Blue,
E_Last
}
for (EMyEnum i = E_First; i < E_Last; i = EMyEnum(i + 1))
{}
또는 연속적이지 않지만 규칙적인 단계 (예 : 비트 플래그)
enum EAnimalCaps
{
E_First,
E_None = E_First,
E_CanFly = 0x1,
E_CanWalk = 0x2
E_CanSwim = 0x4,
E_Last
}
class MyAnimal
{
EAnimalCaps m_Caps;
}
class Frog
{
Frog() :
m_Caps(EAnimalCaps(E_CanWalk | E_CanSwim))
{}
}
for (EAnimalCaps= E_First; i < E_Last; i = EAnimalCaps(i << 1))
{}
답변
열거 형으로는 할 수 없습니다. 아마도 열거 형이 상황에 가장 적합하지 않을 수도 있습니다.
일반적인 규칙은 MAX와 같은 마지막 열거 형 값의 이름을 지정하고 int를 사용하여 루프를 제어하는 데 사용하는 것입니다.