열거 형을 어떻게 반복 할 수 있습니까?


304

방금 ++ 또는 + =와 같은 열거 형에서 표준 수학 연산자를 사용할 수 없다는 것을 알았습니다.

그렇다면 C ++ 열거 형의 모든 값을 반복하는 가장 좋은 방법은 무엇입니까?


2
많은 접근 방법 중 하나 : enum이 충분하지 않은 경우 : C ++에 대한 열거 클래스 . 더 캡슐화 된 것을 원한다면 James Kanze 의이 접근법 을 시도 하십시오 .
Don Wakefield

연결된 항목에는 흥미로운 반응이 있습니다.
Tony

이 답변은 int충분히 크지 않은 문제를 다루지 않는 것 같습니다 ! ( [C++03: 7.2/5])
궤도에서 가벼움 레이스

흥미롭게도 operator++열거 형을 정의 할 수 있습니다 . 그러나 할 수 있습니다 for(Enum_E e = (Enum_E)0; e < ENUM_COUNT; e++). C ++은 열거 형에 대입 연산자를 금지 0하기 Enum_E때문에 캐스트해야합니다 .
weberc2

sizeof 작동 방식과 비슷한 컴파일 시간 연산자가 있으면 열거 형 값으로 구성된 std :: initializer_list 리터럴을 생성 할 수 있으며 솔루션이 있으며 런타임 오버 헤드가 포함되지 않습니다.
jbruni

답변:


263

일반적인 방법은 다음과 같습니다.

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;
}

실제로 열거하려면 열거 형 값을 벡터에 채우고 반복하십시오. 지정된 열거 형 값도 올바르게 처리합니다.


13
예제의 첫 번째 부분에서 'i'를 int가 아닌 Foo 열거 형으로 사용하려면 다음과 같이 정적 캐스트해야합니다. static_cast <Foo> (i)
Clayton

5
또한 루프에서 마지막을 건너 뜁니다. <= 마지막이어야 함
Tony

20
@Tony Last는 건너 뛰어야합니다. 나중에 더 많은 열거 형을 추가하려면 마지막 전에 추가하십시오 ... 첫 번째 예제의 루프는 여전히 작동합니다. "가짜"마지막 열거 형을 사용하면 새 열거 형을 추가 할 때마다 for 루프의 종료 조건을 마지막 "실제"열거 형으로 업데이트 할 필요가 없습니다.
timidpueo

열거 형이 0 인 인덱스이고 엄격하게 연속적 인 경우 메모리를 할당하지 않고 해당 작업을 수행 할 수있는 경우 실제로 메모리를 할당했습니다.
Cloud

1
이 열거 형 정의가 업데이트를 위해 안전하려면 값을 정의해야합니다 UNKNOWN = 0. 또한 default열거 형 값을 전환 할 때 런타임까지 값 처리를 잊어 버린 경우를 숨길 수 있으므로 사례를 삭제하는 것이 좋습니다 . 대신 모든 값을 하드 코딩하고 UNKNOWN필드를 사용하여 비 호환성을 감지 해야합니다 .
Benjamin

53
#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;
}

감사! 당신이있는 거 교차 파일 / 클래스와 MS 호환성 헤더 선언 정수가 아닌 상수로 당신에게 문제를 제공하는 경우, 명시 적으로 내 컴파일러에서 도움이 헤더의 형태로 크기를 세우면하는 것으로 : static const Type All[3];다음 나는 수 있어요 소스에서 초기화하려면 : const MyEnum::Type MyEnum::All[3] = { a, b, c }; 그렇게하기 전에 Error in range-based for...배열의 크기를 알 수 없기 때문에 눈에 띄지 않는 오류가 발생했습니다. 덕분 아웃이 체격 관련 대답
세이지

1
어레이 버전은 복사 붙여 넣기에 매우 친숙합니다. "아니오"또는 "순차 전용"외에 가장 만족스러운 답변입니다. 아마 매크로 친화적입니다.
Paulo Neves

1
이 방법은 항목 수가 적은 열거 형에는 적합하지만 항목 수가 많은 열거 형에는 적합하지 않습니다.
kato2

20

열거 형이 0으로 시작하고 증분이 항상 1 인 경우

enum enumType 
{ 
    A = 0,
    B,
    C,
    enumTypeEnd
};

for(int i=0; i<enumTypeEnd; i++)
{
   enumType eCurrent = (enumType) i;            
}

그렇지 않다면 내가 유일하게 왜 같은 것을 만드는 것 같아

vector<enumType> vEnums;

항목을 추가하고 일반 반복자를 사용하십시오 ....


19

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 덕분)


1
@lepe? 다른 열거 형에 대해 다른 typedef를 만듭니다.
앤드류 나사로

2
@lepe 그것은 에 묶여 std::vector있기 때문에 일반적이지 않다고 말하는 것과 같습니다 . std::vector<foo>foo
Kyle Strand

1
typedef Iterator<color, color::green, color::red> colorIterator;템플릿 인스턴스화 작동 방식을 이해해야합니다.
앤드류 나사로

2
아, 내가 문제를 볼 수 - foo operator*() { ...해야한다 C operator*() { ....
Kyle Strand

1
@KyleStrand : 알았습니다! 그것은 이제 완전히 이해됩니다. 코드를 업데이트해야합니까? 설명해 주셔서 감사합니다.
lepe December

16

이 솔루션이 너무 복잡합니다.

enum NodePosition { Primary = 0, Secondary = 1, Tertiary = 2, Quaternary = 3};

const NodePosition NodePositionVector[] = { Primary, Secondary, Tertiary, Quaternary };

for (NodePosition pos : NodePositionVector) {
...
}

이것이 왜 다운 보트인지 모르겠습니다. 합리적인 해결책입니다.
Paul Brannan 2014

11
출품작을 두 곳에서 관리해야했기 때문이라고 생각합니다.
Ant

C ++는 for (NodePosition pos : NodePositionVector)구문을 허용합니까 ? 내가 아는 한 이것은 Java 구문이며 동등한 것을 수행하려면 C ++의 반복자가 필요합니다.
thegreatjedi

3
@thegreatjedi C ++ 11부터 훨씬 더 간단 할 수 있습니다 : for (auto pos : NodePositionVector) {..}
Enzojz

@thegreatjedi 그 질문을하는 것보다 테스트 프로그램을 검색하거나 컴파일하는 것이 더 빠를 것입니다. 그러나 그렇습니다. C ++ 11이기 때문에 컴파일러는 완벽하게 유효한 C ++ 구문입니다. 컴파일러는 일반적으로 반복자를 통해 동등한 (그리고 훨씬 더 자세한 / 덜 추상화 된) 코드로 변환합니다. cppreference를 참조하십시오 . Enzojz가 말했듯이 C ++ 11도 추가 auto했으므로 (A) 변환 연산자를 사용해야하거나 (B) auto어떤 이유로 든 좋아하지 않는 한 요소 유형을 명시 적으로 선언 할 필요가 없습니다. . 대부분의 범위 for사용자는 autoAFAICT를 사용합니다
underscore_d

9

나는 종종 그런 식으로

    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))
    {}

그러나 비트 단위로 값을 인쇄하는 용도는 무엇입니까?
Anu

1
열거 형을 사용하여 비트 마스크를 만듭니다. 예를 들어 여러 옵션을 단일 변수로 결합한 다음 FOR를 사용하여 모든 옵션을 테스트하십시오. 더 나은 예를 들어 내 게시물을 수정했습니다.
Niki

나는 여전히 그것을 사용할 수 없다 (그리고 당신의 게시물은 여전히 ​​오래된 예를 보여줍니다)! 비트 마스크로 열거 형을 사용하면 실제로 도움이되지만 점을 연결할 수는 없었습니다! 예제에서 조금 자세하게 설명 해 주시겠습니까? 추가 코드도 넣을 수 있습니다.
Anu

@anu 죄송합니다 귀하의 의견을 보지 못했습니다. 비트 마스크 예제로 Frog 클래스를 추가
Niki

8

열거 형으로는 할 수 없습니다. 아마도 열거 형이 상황에 가장 적합하지 않을 수도 있습니다.

일반적인 규칙은 MAX와 같은 마지막 열거 형 값의 이름을 지정하고 int를 사용하여 루프를 제어하는 ​​데 사용하는 것입니다.


여기에 반대를 보여주는 몇 가지 예가 있습니다. 나는 당신이 자신과 모순된다고 진술합니다 (두 번째 줄).
Niki

6

다른 답변에서 다루지 않은 것 = 강력한 형식의 C ++ 11 열거 형을 사용하는 경우 ++또는 그 + int위에 사용할 수 없습니다 . 이 경우 약간 더 지저분한 솔루션이 필요합니다.

enum class myenumtype {
  MYENUM_FIRST,
  MYENUM_OTHER,
  MYENUM_LAST
}

for(myenumtype myenum = myenumtype::MYENUM_FIRST;
    myenum != myenumtype::MYENUM_LAST;
    myenum = static_cast<myenumtype>(static_cast<int>(myenum) + 1)) {

  do_whatever(myenum)

}

3
...하지만 C ++ 11은 다른 답변에 표시된 범위를 소개합니다. :-)
Sage

5

다음 매크로를 시도하고 정의 할 수 있습니다.

#define for_range(_type, _param, _A1, _B1) for (bool _ok = true; _ok;)\
for (_type _start = _A1, _finish = _B1; _ok;)\
    for (int _step = 2*(((int)_finish)>(int)_start)-1;_ok;)\
         for (_type _param = _start; _ok ; \
 (_param != _finish ? \
           _param = static_cast<_type>(((int)_param)+_step) : _ok = false))

이제 당신은 그것을 사용할 수 있습니다 :

enum Count { zero, one, two, three }; 

    for_range (Count, c, zero, three)
    {
        cout << "forward: " << c << endl;
    }

부호없는 정수, 열거 형 및 문자를 통해 앞뒤로 반복하는 데 사용할 수 있습니다.

for_range (unsigned, i, 10,0)
{
    cout << "backwards i: " << i << endl;
}


for_range (char, c, 'z','a')
{
    cout << c << endl;
}

어색한 정의에도 불구하고 매우 잘 최적화되어 있습니다. VC ++에서 디스어셈블러를 보았습니다. 코드는 매우 효율적입니다. 끝내지 말고 세 개의 for 문을 사용하십시오. 컴파일러는 최적화 후 하나의 루프 만 생성합니다! 닫힌 루프를 정의 할 수도 있습니다.

unsigned p[4][5];

for_range (Count, i, zero,three)
    for_range(unsigned int, j, 4, 0)
    {   
        p[i][j] = static_cast<unsigned>(i)+j;
    }

공백이있는 열거 된 유형을 반복 할 수는 없습니다.


1
멋진 해킹입니다! C ++보다 C에 더 적합하지만 말할 수도 있습니다.
einpoklum 2016 년

3
_A1허용되는 이름이 아니며 다음 대문자를 사용하는 선행 밑줄입니다.
Martin Ueding

3

열거 된 유형의 증분 / 감소 연산자를 오버로드 할 수도 있습니다.


1
C 또는 C ++ 열거 유형에서는 연산자를 오버로드 할 수 없습니다. 값의 열거를 에뮬레이트하는 구조체 / 클래스를 만들지 않는 한.
Trevor Hickey

2
C ++을 사용하면 열거 형에 연산자를 오버로드 할 수 있습니다. stackoverflow.com/questions/2571456/…를 참조하십시오 .
Arch D. Robison 21:53에

증가 / 감소를 오버로드하려면 오버플로가 발생했을 때 수행 할 작업을 결정해야합니다.
Eponymous

3

enum에 순차적으로 번호가 매겨 졌다고 가정하면 오류가 발생하기 쉽습니다. 또한 선택된 열거 자에 대해서만 반복 할 수 있습니다. 해당 하위 집합이 작은 경우 명시 적으로 반복하면 우아한 선택이 될 수 있습니다.

enum Item { Man, Wolf, Goat, Cabbage }; // or enum class

for (auto item : {Wolf, Goat, Cabbage}) { // or Item::Wolf, ...
    // ...
}

이것은 내가 생각하는 좋은 옵션입니다. 내가 추측하는 질문을 할 때 사용했던 것보다 새로운 C ++ 사양의 일부 여야합니까?
Adam

예. std :: initializer_list <Item>을 반복합니다. 링크 .
marski

2

스위치에서 열거 형을 사용하면 컴파일러에서 누락 된 사례 COUNT를 경고하기 때문에 최종 COUNT 항목으로 열거 형을 오염시키지 않으려면 다음을 수행하십시오.

enum Colour {Red, Green, Blue};
const Colour LastColour = Blue;

Colour co(0);
while (true) {
  // do stuff with co
  // ...
  if (co == LastColour) break;
  co = Colour(co+1);
}

2

인접한 열거 형에만 작동하는 또 다른 솔루션이 있습니다. C ++에서 깨진 것이기 때문에 그것이 증가하는 곳의 추한 점을 제외하고는 예상되는 반복을 제공합니다.

enum Bar {
    One = 1,
    Two,
    Three,
    End_Bar // Marker for end of enum; 
};

for (Bar foo = One; foo < End_Bar; foo = Bar(foo + 1))
{
    // ...
}

1
을 늘리면 단축 될 수 있습니다 foo = Bar(foo + 1).
HolyBlackCat

감사합니다, HolyBlackCat, 나는 당신의 훌륭한 제안을 통합했습니다! 또한 Riot도 이와 동일한 솔루션을 가지고 있지만 강력한 타이핑 (따라서 더 장황한)을 준수합니다.
Ethan Bradford

2
enum class A {
    a0=0, a3=3, a4=4
};
constexpr std::array<A, 3> ALL_A {A::a0, A::a3, A::a4}; // constexpr is important here

for(A a: ALL_A) {
  if(a==A::a0 || a==A::a4) std::cout << static_cast<int>(a);
}

A는 constexpr std::array어레이가 컴파일러에 의해 인스턴스화 없이도 비 순차 열거를 반복 할 수있다. 이것은 컴파일러의 최적화 휴리스틱 스와 배열의 주소를 취했는지 여부에 달려 있습니다.

내 실험에서, g++9.1 with -O3는 비 순차적 값이 2 개이거나 순차적 인 값이 상당히 많은 경우 위 배열을 최적화합니다 (최대 6 테스트). 그러나 if진술 이있는 경우에만이 작업을 수행 합니다. (순차 배열의 모든 요소보다 큰 정수 값을 비교 한 명령문을 시도했지만 제외되지 않았음에도 불구하고 반복을 인라인했지만 if 문을 생략하면 값이 메모리에 저장되었습니다.) 하나의 비 순차 열거 형의 값 https://godbolt.org/z/XuGtoc] . 이 이상한 행동은 캐시 및 분기 예측과 관련된 깊은 휴리스틱으로 인한 것으로 생각됩니다.

다음은 배열이 항상 인스턴스화되지는 않음을 보여주는 godbolt의 간단한 테스트 반복에 대한 링크 입니다.

이 기술의 가격은 열거 형 요소를 두 번 쓰고 두 목록을 동기화 상태로 유지합니다.


나는 간단한 범위와 같은 for-loop 의미를 좋아하고 그것이 더 많이 진화 할 것이라고 생각 하므로이 솔루션을 좋아합니다.
rtischer8277

2

Bjarne Stroustrup의 C ++ 프로그래밍 언어 책에서 operator++특정에 대한 과부하를 제안하고 있음을 읽을 수 있습니다 enum. enum사용자 정의 유형이며 이러한 특정 상황에 대해 언어에 과부하 연산자가 있습니다.

다음을 코딩 할 수 있습니다.

#include <iostream>
enum class Colors{red, green, blue};
Colors& operator++(Colors &c, int)
{
     switch(c)
     {
           case Colors::red:
               return c=Colors::green;
           case Colors::green:
               return c=Colors::blue;
           case Colors::blue:
               return c=Colors::red; // managing overflow
           default:
               throw std::exception(); // or do anything else to manage the error...
     }
}

int main()
{
    Colors c = Colors::red;
    // casting in int just for convenience of output. 
    std::cout << (int)c++ << std::endl;
    std::cout << (int)c++ << std::endl;
    std::cout << (int)c++ << std::endl;
    std::cout << (int)c++ << std::endl;
    std::cout << (int)c++ << std::endl;
    return 0;
}

테스트 코드 : http://cpp.sh/357gb

내가 사용하고있는 마음 enum class. 코드 enum도 잘 작동합니다 . 그러나 나는 enum class형식이 강하고 컴파일 타임에 실수를 저 지르지 않기 때문에 선호합니다 .


이 게시물에 공감대가 제출되었습니다. 왜 질문에 대답하지 않습니까?
LAL

그 이유는 아마도 이것이 건축 적으로 말하는 끔찍한 해결책이기 때문일 것입니다. 특정 구성 요소 (열거)에 바인딩 된 전역 의미 논리를 강제로 작성해야합니다. + 연산자도, 그 어떤 매체 - 대규모 프로젝트에 대한 지속하지 않은 방법으로, 그것이이 비얀 스트로브 스트 룹의 추천에서 오는 놀라운 아닌, 일 소프트웨어 아키텍처 다시는 공상 과학 소설 같았다
Manjia

원래 질문은에 연산자를 갖는 것 enum입니다. 건축적인 질문이 아니 었습니다. 나는 2013 년 C ++이 공상 과학이라고 믿지 않습니다.
LAL

1

MS 컴파일러의 경우 :

#define inc_enum(i) ((decltype(i)) ((int)i + 1))

enum enumtype { one, two, three, count};
for(enumtype i = one; i < count; i = inc_enum(i))
{ 
    dostuff(i); 
}

참고 : 이것은 간단한 템플릿 사용자 정의 반복자 답변보다 훨씬 적은 코드입니다.

typeof대신 GCC를 사용 하여이 작업을 수행 할 수는 decltype있지만 현재 컴파일 할 수있는 컴파일러는 없습니다.


이것은 decltype표준 C ++가 된 후 ~ 5 년이 지나서 작성 되었으므로 오래된 typeofGCC 에서 오래된 것을 권장하지 않아야합니다 . 모호한 최근 GCC가 decltype잘 처리 됩니다. 다른 문제가 있습니다 : C 스타일 캐스트는 권장하지 않으며 매크로가 더 나쁩니다. 적절한 C ++ 기능은 동일한 일반 기능을 제공 할 수 있습니다. static_cast& 템플릿 함수 를 사용하도록 다시 작성하는 것이 좋습니다 template <typename T> auto inc_enum(T const t) { return static_cast<T>(static cast<int>(t) + 1); }. 그리고 캐스트는 필요하지 않습니다 enum class. 대안으로, 연산자는 enum유형 (TIL) 별로 오버로드 될 수 있습니다.
underscore_d

1
typedef enum{
    first = 2,
    second = 6,
    third = 17
}MyEnum;

static const int enumItems[] = {
    first,
    second,
    third
}

static const int EnumLength = sizeof(enumItems) / sizeof(int);

for(int i = 0; i < EnumLength; i++){
    //Do something with enumItems[i]
}

이 솔루션은 메모리에 불필요하게 정적 변수를 생성하는 반면 enum의 목적은 인라인 된 상수에 대한 '마스크'를 만드는 것입니다.
TheArquitect

constexpr static const int enumItems[]
Mohammad Kanan

0

C ++에는 내부 검사가 없으므로 런타임에 이러한 종류의 것을 결정할 수 없습니다.


1
열거 형을 반복하는 데 "내성 검사"가 필요한 이유를 설명해 주시겠습니까?
Jonathan Mee

어쩌면 용어는 Reflection ?
kͩeͣmͮpͥ ͩ

2
나는 2 가지를 말하려고 노력하고있다 : 1) C ++은 많은 다른 대답에 따라 이것을 달성 할 수 없으므로 그것을 할 수 없다면, 링크 또는 추가 설명이 필요합니다. 2) 그것은 현재의 형태로 이것은 기껏해야 의견이며, 대답은 아닙니다.
Jonathan Mee

내 대답을 Downvote-당신은 그것을 정당화하는 것 이상을 생각합니다
kͩeͣmͮpͥ ͩ

1
나는 다시 2 개의 의견을 남길 것입니다 : 1) 나는 downvote를받는 것이 사이트 참여를 자극한다는 것을 알기 때문에 downvote하지 않습니다. 나는 비생산적이라는 것을 알았습니다. 당신은 내가 그렇지 않은 것을 이해합니다.이 경우 하향식 답변을 삭제하는 대신 정교하게 선호합니다.
Jonathan Mee

0

열거 형 값이 순차적임을 알고 있으면 (예 : Qt : Key 열거 형) 다음을 수행 할 수 있습니다.

Qt::Key shortcut_key = Qt::Key_0;
for (int idx = 0; etc...) {
    ....
    if (shortcut_key <= Qt::Key_9) {
        fileMenu->addAction("abc", this, SLOT(onNewTab()),
                            QKeySequence(Qt::CTRL + shortcut_key));
        shortcut_key = (Qt::Key) (shortcut_key + 1);
    }
}

예상대로 작동합니다.


-1

정수 배열을 만들고 배열을 반복하지만 마지막 요소를 -1로 만들고 종료 조건에 사용하십시오.

열거 형이 다음과 같은 경우 :

enum MyEnumType{Hay=12,Grass=42,Beer=39};

그런 다음 배열을 만듭니다.

int Array[] = {Hay,Grass,Beer,-1};

for (int h = 0; Array[h] != -1; h++){
  doStuff( (MyEnumType) Array[h] );
}

-1 검사가 물론 요소 중 하나와 충돌하지 않는 한 표현의 정수에 관계없이 분해되지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.