2013-02-27 7 views
10

C++ 11 표준 (글쎄, n3242 초안)과 인터넷을 샅샅이 뒤졌지만 정확한 대답을 찾을 수 없었습니다. 아래의 코드는 Visual Studio 2010뿐 아니라 clang 3.2 및 g ++ 4.7.2에서도 제대로 컴파일되지만 대신 오류가 발생할 것으로 예상됩니다. typedef와 동일한 범위에서 동일한 이름에 대한 선언 사용

#include <iostream> 
#include <typeinfo> 


typedef int a_t; 


namespace a_ns 
{ 
class a_t {}; 
} 


using a_ns::a_t; 


int main() 
{ 
    a_t a; 
    std::cout << typeid(a).name() << std::endl; 
    return 0; 
} 

함께 내장 :

clang -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++ 
g++ -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++ 
cl -EHsc -GR a.cpp 

그 소리와 g ++ 가 int 타입을 나타냅니다 보인다 실행 인쇄 "I"를 생성하고 형식 정의가 이겼다. cl 생성 된 실행 파일 "class a_ns :: a_t"는 Visual Studio에서 선언을 더 많이 사용하는 것을 좋아하는 것으로 보입니다.

코드는 다음 표준 발췌문에 따라 컴파일되지 않을 것으로 예상됩니다. "이미 선언 범위 내에서 선언 충돌을 사용하는 대상"과 비슷한 오류가 발생할 것으로 예상됩니다.

7.1.3.6 Similarly, in a given scope, a class or enumeration shall not be declared with the same name as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself.

7.3.3.1 A using-declaration introduces a name into the declarative region in which the using-declaration appears.

7.3.3.2 Every using-declaration is a declaration [...]

이 아마 뭔가 내가이 동작을 설명 표준에서 누락하고 (또는 내가 명백한을보고 너무 피곤하다),하지만 나는 그것을 찾을 수 없습니다.

감사합니다.

답변

4

맞습니다. 표시 한 내용에 따르면 코드가 유효하지 않습니다. 또한 3.3.1p4도 있는데, 이는 무효화합니다 (7.3.3p13 참조).

실제 테스트에서는 ICC로 테스트 한 결과 예상대로 거부합니다.

+0

'main()'의 본문이 비어 있으면 해당 프로그램도 유효하지 않습니까? 7.1.3/6 절은 "* 주어진 범위 내에서 typedef 지정자는 ** 다른 유형을 참조하기 위해 해당 범위에서 선언 된 모든 유형의 이름을 ** 재정의하는 데 사용되어서는 안됩니다. * [예제 :'class complex {/ ... /}; typedef int complex; // 오류 : 재정의 '-end example *] "*. 질문에, typedef는 이름을 "재정의"하지 않는다. 'using' 선언 다음에 이동할 때, 모든 컴파일러는 에러를 낸다. –

+0

@ mainy가 비어 있다면, 우리가 찾은 따옴표에 따르면, 역시 유효하지 않을 것입니다. 다른 인용 부호가 적용되는지 여부는 부적합합니다. 일반적으로 이름의 재정의는 class A {}에 대해 발생합니다. typedef AA;'(처음에는 class-name 뿐이며 typedef-name이기도합니다. 이름이 재정의됩니다. 왜냐하면 나중에 하나의 이름 만 있지만 구문 적 속성을 모두 가지고 있기 때문입니다. C 모델). –

+0

확인해 주셔서 감사합니다. +1 –