C ++에서 열거 형을 선언 할 때 typedef를 사용하는 이유는 무엇입니까?


183

몇 년 동안 C ++을 작성하지 않았으므로 이제 C ++로 돌아 가려고합니다. 나는 이것을 가로 질러 포기하는 것에 대해 생각했다.

typedef enum TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;

이게 뭐야? typedef키워드 가 왜 여기에 사용됩니까? TokenType이 선언에서 이름 이 두 번 나타나는 이유는 무엇 입니까? 시맨틱은 이것과 어떻게 다른가요?

enum TokenType
{
    blah1 = 0x00000000,
    blah2=0x01000000,
    blah3=0x02000000
};

답변:


156

C에서 열거 형을 첫 번째 방법으로 선언하면 다음과 같이 사용할 수 있습니다.

TokenType my_type;

두 번째 스타일을 사용하면 다음과 같이 변수를 선언해야합니다.

enum TokenType my_type;

다른 사람들이 언급했듯이 C ++에서는 차이가 없습니다. 내 생각에는 이것을 작성한 사람이 C 프로그래머이거나 C 코드를 C ++로 컴파일하는 것입니다. 어느 쪽이든 코드의 동작에는 영향을 미치지 않습니다.


12
귀하의 질문은 C에 대해서만 정확하지만 C ++에는 맞지 않습니다. C ++에서는 열거 형과 구조체를 typedef가있는 것처럼 직접 사용할 수 있습니다.
David Rodríguez-dribeas

7
글쎄요, 그러나 이것은 실제로 "무엇을 의미합니까?"라는 질문에 대한 실제 질문에 대한 답입니다.
BobbyShaftoe

이것은 기술적으로 typedef 또는 열거 형입니까?
Miek

5
둘 다입니다. enum TokenType_ {...}; typedef enum TokenType_ TokenType;
Ryan Fox

대답은 완료되었지만 요점은 TokenType입니다. 열거 형 선언 후 형식 이름을 선언합니다. 따라서 대답은 100 % 완전하지 않습니다. '첫 번째 방법'을 선언하면 열거 형과 하나의 구문으로 열거 형인 새 유형 이름을 지정합니다. 답변이 도움이되었지만 조금 개선 될 수 있다고 생각합니다. 어쩌면 나는 투표를하기에 너무 가혹했다. 그래서 나는 결국 그것을 공표했다. 내가 정말로 확신한다면, 나는 답변을 편집 / 개선하는 데 약탈 할 것입니다 ... 그러나 이것은 꽤 좋은 대답입니다
Ross Youngblood

97

다음과 같은 경우 C의 C 유산입니다.

enum TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
};

다음과 같은 작업을 수행해야합니다.

enum TokenType foo;

그러나 이렇게하면 :

typedef enum e_TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;

당신은 선언 할 수 있습니다 :

TokenType foo;

그러나 C ++에서는 이전 정의 만 사용하고 마치 C typedef에있는 것처럼 사용할 수 있습니다.


1
당신이 말하는 것은 C에서는 사실입니다. C ++에서는 그렇지 않습니다.
Jonathan Leffler

49
마지막 문장에서 내가 말한 것이 아닌가?
mat

2
@mat 나는 마지막 문장에 대한 당신의 의견을 올렸습니다.
AR

20

당신은 그것을 할 필요가 없습니다. C (C ++ 아님) 에서는 열거 형의 데이터 요소를 참조하기 위해 enum Enumname 을 사용해야했습니다 . 단순화하기 위해 단일 이름 데이터 형식 으로 typedef 할 수있었습니다 .

typedef enum MyEnum { 
  //...
} MyEnum;

열거 형의 매개 변수를 취하는 함수를 다음과 같이 정의 할 수 있습니다.

void f( MyEnum x )

더 이상

void f( enum MyEnum x )

typename의 이름이 열거 형의 이름과 같을 필요는 없습니다. 구조체에서도 마찬가지입니다.

반면에 C ++에서는 열거 형, 클래스 및 구조체에 이름으로 유형에 직접 액세스 할 수 있으므로 필요하지 않습니다.

// C++
enum MyEnum {
   // ...
};
void f( MyEnum x ); // Correct C++, Error in C

실제로 나는 이것이 왜 "왜"다른지를 명확하게 설명하기 때문에 일반적으로 받아 들여지는 것보다 더 나은 대답이라고 생각합니다.
Ross Youngblood

11

C에서는 유형을 열거 형 이외의 것으로 변경할 수 있기 때문에 좋은 스타일입니다.

typedef enum e_TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;

foo(enum e_TokenType token);  /* this can only be passed as an enum */

foo(TokenType token); /* TokenType can be defined to something else later
                         without changing this declaration */

C ++에서는 열거 형을 정의하여 C ++ 또는 C로 컴파일 할 수 있습니다.


당신은 말하는 것을 의미하지 In C++ you can *typedef* the enum so that it will compile as C++ or C.않습니까? 당신은 말했다 : In C++ you can define the enum so that it will compile as C++ or C.내가 당신 define을 어떻게 바꿨는지 주목하십시오 typedef. 글쎄 ... 나는 typedefing 정의하고 있다고 생각 한다 .
Gabriel Staples

6

C에서 이월


'초기'한정자가 관련이 있다고 Dunno; 열거 형 접두사없이 유형 이름을 사용하려면 C로 작성하십시오.
Jonathan Leffler

1
진실. 삭제하겠습니다. 오랫동안 C 사양을 따르지 않았습니다. 나는 c / c ++ 구별을 확인하기에는 너무 게으르다 ...- 1.
Tim

6

어떤 사람들은 C에 네임 스페이스가 없지만 기술적으로 올바르지 않다고 말합니다. 세 가지가 있습니다.

  1. 태그 ( enum, unionstruct)
  2. 라벨
  3. (다른 모든 것)

typedef enum { } XYZ;익명 열거를 선언하고 이름이있는 전역 네임 스페이스로 가져옵니다 XYZ.

typedef enum ABC { } XYZ;ABC태그 네임 스페이스에 명명 된 열거 형을 선언 한 다음로 글로벌 네임 스페이스로 가져옵니다 XYZ.

어떤 사람들은 별도의 네임 스페이스를 사용하지 않고 모든 것을 typedef합니다. 다른 사람들은 네임 스페이스를 원하기 때문에 typedef하지 않습니다.


이것은 정확하지 않습니다. 구조체, 공용체 및 열거 형은 태그 이름으로 참조됩니다 (명명하지 않은 경우 익명). 유형과 태그에는 별도의 네임 스페이스가 있습니다. 태그와 이름이 정확히 같은 유형을 사용하여 컴파일 할 수 있습니다. 그러나 열거 형에 구조체와 동일한 태그가있는 경우 동일한 태그가있는 2 개의 구조체 또는 2 개의 열거 형과 정확히 같은 컴파일 오류입니다. 또한 goto의 레이블이 별도의 네임 스페이스라는 것을 잊어 버렸습니다. 레이블은 태그와 동일한 이름 또는 식별자 일 수 있지만 유형은 아니지만 식별자는 태그와 이름은 같지만 유형은 아닙니다.
Rich Jahn

3

이것은 오래된 종류이지만 어쨌든 올해 초에 그것을 보았을 때 내가 고맙게 생각한 것처럼 입력하려고하는 링크에 감사 드리기를 바랍니다.

여기 있습니다 . 나는 불쾌한 타입 정의를 파악해야 할 때 항상 내 마음 속에있는 설명을 인용해야합니다.

변수 선언에서 소개 된 이름은 해당 유형의 인스턴스입니다. [...] 그러나 typedef키워드가 선언 앞에 오면 소개 된 이름은 해당 유형의 별명입니다.

많은 사람들이 이전에 말했듯이 C ++ 에서 열거 형을 선언하는 typedef를 사용할 필요가 없습니다 . 그러나 이것이 typedef의 구문에 대한 설명입니다! 나는 그것이 도움이되기를 바랍니다 (아마도 10 년이 지났지 만 이러한 종류의 것들을 이해하기 위해 고군분투하는 사람은 OP가 아닐 것입니다).


1

일부 C 코드 스타일 가이드에서 typedef 버전은 "명확성"및 "간단 성"에 적합하다고합니다. typedef가 선언 된 객체의 실제 특성을 모호하게하기 때문에 동의하지 않습니다. 사실, 나는 C 변수를 선언 할 때 객체가 실제로 무엇인지 분명히하고 싶기 때문에 typedef를 사용하지 않습니다. 이 선택은 오래된 코드 조각이 실제로하는 일을 더 빨리 기억하는 데 도움이되고 나중에 코드를 유지 관리 할 때 다른 사람들을 도울 것입니다.


1

"이유"질문에 대한 실제 답변은 (이 오래된 질문에 대한 기존 답변에서 놀랍게도 무시됩니다)이 enum선언은 아마도 C 및 C ++ 코드로 크로스 컴파일 할 수있는 헤더 파일에있을 것입니다 (예 : C 및 C ++ 구현 파일 모두에 포함됨). 이러한 헤더 파일을 작성하는 기술은 저자가 두 언어 모두에서 적절한 호환 의미를 갖는 언어 기능을 선택할 수있는 능력에 의존합니다.

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