어떤 네임 스페이스가 있고 규칙은 무엇입니까?


9

참고 :이 질문은 name space아닙니다 namespace.

C ++ 표준에는에 대한 참조가 name space있지만 이에 대한 정의는 없습니다. 표준에 따르면 레이블과 매크로는 다른 이름 공간에 있습니다. 다른 모든 참조 name space는 다음과 같이 C / C ++ 호환성 섹션에 있습니다 ( 현재 초안 ).

이것은 C와 C ++ 사이의 몇 가지 비 호환성 중 하나이며, 이름을 단일 범위에서 유형으로 선언하고 유형이 아닌 이름으로 정의 할 수있는 새로운 C ++ 네임 스페이스 정의에 기인 할 수 있습니다. 유형 이름을 지정하고 키워드 class, struct, union 또는 enum을 사용하여 유형 이름을 참조해야합니다. 이 새로운 네임 스페이스 정의 는 C ++ 프로그래머에게 중요한 표기법 편의를 제공하고 사용자 정의 유형을 기본 유형의 사용과 최대한 유사하게 사용하도록 도와줍니다.

새로운 네임 스페이스 정의 는 무엇입니까 ? 표준에서 어디서 찾을 수 있습니까? 정확한 규칙은 무엇입니까? 규칙은 "비 유형 숨기기 유형"보다 더 복잡한 것 같습니다. 마찬가지로, 이것은 컴파일되지 않습니다 :

typedef int Foo; // Foo is a type
void Foo();      // not a type, but compile error, instead of hiding

그러나 이것은 :

struct Foo { }; // Foo is a type as well
void Foo();     // This hides the type Foo. "struct Foo" refers to the type

그리고 이것은 컴파일되지 않습니다 :

struct Foo { };   // Type
namespace Foo { } // Non-type, but compiler error instead of hiding

실용적인 관점은 네임 스페이스가 모든 공용 멤버 (하위 클래스)를 가진 싱글 톤 클래스라는 것입니다. 날
빌려주지 말아

2
@ peterh-ReinstateMonica는 질문을 다시 읽었습니다.
YSC

FWIW, 귀하의 링크는 관련 섹션으로 연결됩니다. 영향을받는 하위 조항 : [class.name] [[dcl.typedef] 참조] 규칙의 작동 방식에 대해서는 해당 섹션을 볼 수 있습니다.
NathanOliver

레이블 [stmt.label]/1과 매크로에 대한 이름 공간이 두 개 이상 있습니다 [cpp]/8.
YSC

1
설명과 예제 둘 다 이론적 근거가 말하는 것과 반대되는 것을 보여주는 것이 다소 흥미 롭습니다. 유형이 아닌 이름을 숨기는 유형 이름 초안 상태를 감안할 때 해당 단락이 변경 될 것으로 예상합니다.
molbdnilo

답변:


2

이름 공간 용어는 더 이상 ISO C 표준에 잘 확립 할 수있다; ISO C11 인용 :

식별자의 네임 스페이스

특정 식별자의 둘 이상의 선언이 번역 단위의 어느 시점에서나 볼 수있는 경우, 구문 문맥은 다른 엔티티를 참조하는 사용을 명확하게합니다. 따라서 다음과 같이 다양한 범주의 식별자에 대해 별도의 네임 스페이스가 있습니다.

  • 라벨 이름 (라벨 선언 및 사용의 구문에 의해 명확 해짐);
  • 키워드 struct, union 또는 enum의 구조, 공용체 및 열거 형 태그 (any32에 의해 명확화 됨);
  • 구조 또는 조합원; 각 구조 또는 공용체에는 멤버에 대해 별도의 네임 스페이스가 있습니다 (. 또는-> 연산자를 통해 멤버에 액세스하는 데 사용되는 표현식 유형에 따라 명확함).
  • 일반 식별자 (일반 선언자 또는 열거 상수로 선언)라고하는 다른 모든 식별자

그러나 C ++ 의 새로운 네임 스페이스 정의최근 어떤 식 으로든 아니 었으며 , ISO C ++ 표준이 98 년에 도입 된 이후로 현재 형식 으로 [diff.class] / 1에서 설명되었습니다 . OP가 인용 한 [diff.class] / 1에 따라 ISO C와 다른 맥락에서 어떤 길이로도 언급 된 적이있다.

우리는 ISO C11 / 6.2.3에 의지와 함께 결합해야 Afaics [diff.class]의 응집력하고 완전한 설명은 ISO C ++ 표준의 / 1 ++ C의 (새) 이름 공간 정의 , 적은 우리는 ISO를 채찍질 C ++ 표준 (예 : [basic.scope.hiding] , [class.name] / 2 , [stmt.label] / 1 , [cpp.replace] / 8 등)은 적용 방법과 위치를 확인합니다.

[클래스 이름] / 2

클래스 선언은 클래스 이름을 선언하는 범위에 클래스 이름을 도입하고 클래스, 변수, 함수 또는 해당 이름의 다른 선언을 둘러싸는 범위에서 숨 깁니다. [...]

[stmt.label] / 1

[...] 레이블은 자체 네임 스페이스를 가지며 다른 식별자를 방해하지 않습니다 [...]

[cpp.replace] / 1

[...] 매크로 이름에는 하나의 네임 스페이스가 있습니다. [...]


1

C (6.2.3 식별자의 네임 스페이스)에서 네임 스페이스의 개념은 다음과 같이 정의됩니다.

1 번역 단위의 어느 시점에서든 특정 식별자의 선언이 둘 이상 보이는 경우, 구문 적 문맥은 다른 엔티티를 나타내는 사용을 명확하게합니다. 따라서 다음과 같이 다양한 범주의 식별자에 대해 별도의 네임 스페이스가 있습니다.

— 라벨 이름 (라벨 선언 및 사용의 구문에 의해 명확 해짐);

— 키워드 struct, union 또는 enum의 구조, 공용체 및 열거 형 태그 (any32에 따라 명확하게 표시됨);

— 구조 또는 조합원; 각 구조 또는 공용체에는 멤버에 대해 별도의 네임 스페이스가 있습니다 (. 또는-> 연산자를 통해 멤버에 액세스하는 데 사용되는 표현식 유형에 따라 명확함).

— 일반 식별자 (일반 선언자 또는 열거 상수로 선언)라고하는 다른 모든 식별자.

예를 들어, 구조 태그 이름은 다른 이름 공간에 속하기 때문에 함수 이름과 일치 할 수 있습니다. 키워드를 사용해야 할 때 구조 태그 이름으로 구조를 지정할 때 struct. 예를 들어 이러한 선언은 충돌하지 않습니다.

struct s
{
    int s;
};

void s( void );

struct s s1;

이 코드 스 니펫에서 s구조 s 의 태그 이름은 키워드와 함께 지정되어야하므로 함수 이름과 충돌하지 않습니다 struct.

C ++에서는 키워드없이 구조 태그 이름을 사용할 수 있습니다 struct.

예를 들어

struct s
{
    int s;
};

s s;

올바른 코드입니다. 이 선언에서

s s;

선언 된 식별자의 이름은 s구조 이름을 숨 깁니다. 그렇다면 예를 들어 쓸 것입니다.

s s1;

이 문장에서 s는 위에 선언 된 식별자의 이름으로 간주되기 때문에 컴파일러는 오류를 발생시킵니다. 모호성을 해결하려면 키워드 struct를 사용해야합니다.

struct s
{
    int s;
};

s s;

struct s s1;

이것은 C ++ 20 표준 (6.3.1 선언적 영역 및 범위)의 다음 인용문에 설명되어 있습니다.

4 단일 선언 영역에 일련의 선언이 주어 졌는데 각 선언 영역에는 동일한 규정되지 않은 이름이 지정되어 있습니다.

(4.1) — 그것들은 모두 같은 개체를 참조하거나, 기능과 기능 템플릿을 참조해야한다. 또는

(4.2) — 정확히 하나의 선언은 typedef 이름이 아닌 클래스 이름 또는 열거 이름을 선언하고 다른 선언은 모두 동일한 변수, 비 정적 데이터 멤버 또는 열거자를 참조하거나 모두 함수 및 함수 템플릿을 참조해야합니다. ; 이 경우 클래스 이름 또는 열거 이름이 숨겨집니다 (6.3.10). [ 참고 : 네임 스페이스 이름 또는 클래스 템플릿 이름은 선언 영역 (10.3.2, 17 항)에서 고유해야합니다. — 끝 참고 ]

인용 부호에서 알 수 있듯이 네임 스페이스 이름은 선언 영역에서 고유해야합니다. 이 선언들은

struct Foo { };
namespace Foo { } 

잘못되었습니다.

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