C ++에서 "using"선언의 범위는 무엇입니까?


100

C ++에서 'using'선언을 사용하여 std :: string 및 std :: vector를 로컬 네임 스페이스에 추가합니다 (불필요한 'std ::'입력을 저장하기 위해).

using std::string;
using std::vector;

class Foo { /*...*/ };

이 선언의 범위는 무엇입니까? 헤더에서이 작업을 수행하면 헤더를 포함하는 모든 cpp 파일에 이러한 '사용'선언을 삽입합니까?


18
여기 다른 답변에서 명확하지 않은 경우를 대비하여 : -include 파일 / 헤더의 파일 범위에 선언 (또는 지시문)을 넣지 마십시오 ! usingusing이는 헤더 사용자에게 골칫거리가 될 것입니다.
Michael Burr

사실, 넣지 마십시오 using선언 (한층 유력한 이유로 지시어를 헤더에) 전혀 , 심지어 네임 스페이스에! 이로 인해 발생하는 문제에 대해서는 네임 스페이스 내에서 선언을 사용하는 범위를 참조하십시오 .
Nils von Barth

@NilsvonBarth : 약간 지나치게 단순화되었습니다. using클래스 및 함수 범위에서 사용 하는 것은 논의 된 문제와 관련하여 안전합니다.
Sebastian Mach


ADL C ++ 조회 기능에 대해 읽어 볼 수 있습니다 .
Alexis Wilke 19 년

답변:


59

C ++에서 헤더 파일을 #include하면 헤더 파일의 전체 내용이 소스 파일에 포함 된 지점에 배치됩니다. 따라서 using선언이있는 using파일을 포함하면 해당 헤더 파일을 포함하는 각 파일의 맨 위에 선언 을 배치하는 것과 똑같은 효과가 있습니다.


51
... 일반적으로 나쁜 것입니다.
Catskul

17
그러나 using선언을 내부에 넣으면 namespace해당 네임 스페이스의 범위로 제한되므로 일반적으로 괜찮습니다 (특정 요구 사항 및 스타일에 대한 일반적인 경고 포함).
Zero

1
...하지만 네임 스페이스 내부에 using을 넣는 경우 일반적으로 좋지 않은 생각을 우회하려고 시도하지 않는지 확인합니다. 예를 들어 네임 스페이스 Y 외부에서 선언 된 클래스 메서드를 다른 내부에 넣을 수 없습니다. 네임 스페이스 X, 로컬에서 네임 스페이스 X를 사용할 수 있도록합니다. 이것이 우리가 처음에 네임 스페이스 :: 리졸버를 사용하는 이유입니다. 매크로 (코드 냄새를 쉽게 유발할 수 있음) 또는 더 나은 입력 문제가 그렇게 큰 경우에는 네임 스페이스 만 사용할 자체 소스 .cpp로 분리하십시오.
osirisgothra

1
이 답변과 유사한 답변은 좋은 조언이지만 질문에 답변하지 않습니다.
Emile Cormier

116

using선언을 차단하는 헤더 파일에는 특별한 것이 없습니다 . 컴파일이 시작되기 전에 간단한 텍스트 대체입니다.

using선언을 범위로 제한 할 수 있습니다 .

void myFunction()
{
   using namespace std; // only applies to the function's scope
   vector<int> myVector;
}

12
함수 내에서 사용할 수있을 거라고는 생각도 못했어요!
Agostino 2015 년

1
나는 하나의 "conglomerator"유형의 파일에 의해 사용되는 많은 네임 스페이스를 가지고 있고, 각 테스트는 특정 네임 스페이스의 것을 사용했기 때문에 gmock 단위 테스트는 매우 지루했고, 나는 각각의 모든 변수를 한정해야한다고 생각했습니다. 사용하여 using함수 내에서 (심지어 gtest TEST매크로를!) 훨씬 더 내 인생을 만든다!
dwanderson

54

using 문의 범위는 코드에서 위치에 따라 다릅니다.

  • 파일의 맨 위에 위치하며 해당 파일 전체에 범위가 있습니다.
  • 이것이 헤더 파일 인 경우 해당 헤더를 포함하는 모든 파일에 범위가 있습니다. 일반적으로 이것은 예상치 못한 부작용을 일으킬 수 있으므로 " 좋은 생각아닙니다 "
  • 그렇지 않으면 using 문은 발생 지점부터 블록 끝까지 포함하는 블록 내에 범위를 갖습니다. 메서드 내에 배치되면 해당 메서드 내에 범위가 있습니다. 클래스 정의 내에 배치되면 해당 클래스 내에 범위가 있습니다.

5
using클래스 범위 내 에서 문 을 추가 할 수 없다고 생각했습니다 ...? 나는 std::온통 타이핑을 피하고 싶기 때문에 OP와 같은 질문을했습니다 . 나는 스마트 포인터와 함께 많은 벡터를 사용하는 클래스를 얻었고 5 개의 문자 std::접두사는 많은 줄 길이를 추가합니다. 그래서 using클래스를 포함하는 네임 스페이스 내의 지시문이 괜찮은지 궁금합니다 . (심지어 헤더 내 경우.)
thomthom

5
범위 내에 있으면 namespace { ... }어떨까요?
einpoklum 2015

따라서 완전히 다음과 같이 작성할 수 있습니다. {using namespace blabla; 클래스 blah {}; } 그리고 그 사용은 클래스에만 적용됩니까?
Dinaiz

8

범위는 using 선언이있는 범위입니다.

이것이 전역 범위 인 경우 전역 범위에 있습니다. 헤더 파일의 전역 범위에있는 경우 헤더를 포함하는 모든 소스 파일의 전역 범위에 있습니다.

따라서 일반적인 조언은 헤더 파일의 전역 범위에서 선언을 사용하지 않는 것 입니다.


3
그것은 충분히 강하지 않습니다. Do n't로 피하십시오
Martin York

1
BUt 회피는하지 않는 것보다 강력합니다. "다른 차를 치지 마십시오"
bobobobo

6

인용 된 경우 파일 ( "번역 단위")은이를 포함하는 모든 파일을 의미합니다.

클래스 내부에 using 문을 넣을 수도 있습니다.이 경우 해당 클래스에만 적용됩니다.

일반적으로 헤더에 네임 스페이스를 지정해야하는 경우 필요한 모든 식별자를 완전히 정규화하는 것이 가장 좋습니다.


using클래스 의 선언은 클래스 외부와 같은 방식으로 작동하지 않습니다. 예를 들어, 클래스 의 범위로 가져 오는 cout대신 사용할 수 없습니다 std::cout.
Zero

2

맞아요. 범위는 using선언 을 사용하는 모듈입니다 . 모듈에 포함 된 헤더 파일에 using선언이있는 경우 해당 선언의 범위는 해당 모듈과 동일한 헤더를 포함하는 다른 모듈이됩니다.


1

그들이 "하지 마라"라고 말할 때 다소 부적합한 댓글이 몇 개 있습니다. 너무 엄격하지만 괜찮을 때 이해해야합니다.

글쓰기 using std::string는 결코 괜찮지 않습니다. using ImplementationDetail::Foo자신의 헤더에 작성 하면 해당 헤더가 ImplementationDetail :: Foo를 선언 할 때도 괜찮을 수 있습니다. 예

namespace MyNS {
    namespace ImplementationDetail {
        int Foo;
    }
    using ImplementationDetail::Foo;
}

1
헤더 사용자는 다음과 같이 쓸 수 있습니다.MyNS::Foo
Peter

더 좋은 예는 using boost::posix_time::ptime. 물론 사용자는 쓸 수 MyNS::ptime있지만 그것은 세상의 끝이 아니며 MyFunction(ptime a, ptime b).
Zero

5
이다 using std::string결코 좋아? 많은 std::접두사 를 저장하기 위해 자신의 네임 스페이스에서도 ?
thomthom

@thomthom 자신의 네임 스페이스와 같은 범위에 래핑 되어도 괜찮습니다.
jcoffland 2011
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.