왜“using namespace std;” 나쁜 습관으로 간주됩니까?

Sep 21 2009

나는 다른 사람들로부터 using namespace std;코드 를 작성 하는 것이 잘못되었으며 대신 std::coutstd::cin직접 사용해야한다고 들었습니다 .

using namespace std;나쁜 습관 으로 간주됩니까? 비효율적입니까 아니면 모호한 변수 ( std네임 스페이스 의 함수와 동일한 이름을 공유하는 변수)를 선언 할 위험이 있습니까? 성능에 영향을 줍니까?

답변

2351 GregHewgill Sep 21 2009 at 10:13

이것은 성능과 전혀 관련이 없습니다. 그러나 이것을 고려하십시오. Foo와 Bar라는 두 개의 라이브러리를 사용하고 있습니다.

using namespace foo;
using namespace bar;

모든 것이 잘 작동 Blah()하며 Foo와 Quux()Bar에서 문제없이 전화 를 걸 수 있습니다. 그러나 언젠가는 Foo 2.0의 새 버전으로 업그레이드하여 Quux(). 이제 충돌이 생겼습니다. Foo 2.0과 Bar 모두 Quux()전역 네임 스페이스로 가져옵니다 . 특히 함수 매개 변수가 일치하는 경우 수정하는 데 약간의 노력이 필요합니다.

foo::Blah()및 을 사용했다면 bar::Quux()의 도입은 foo::Quux()이벤트가 아니었을 것입니다.

1442 sbi Sep 21 2009 at 16:26

나는 Greg가 쓴 모든 것에 동의 하지만 덧붙이고 싶습니다 : Greg가 말한 것보다 더 나빠질 수 있습니다!

Library Foo 2.0은 Quux()몇 년 동안 호출 한 코드 Quux()보다 일부 호출에 대해 분명하게 더 잘 일치 하는 함수를 도입 할 수 bar::Quux()있습니다. 그런 다음 코드는 여전히 컴파일 되지만 자동으로 잘못된 함수를 호출하고 신이 무엇을 알고 있습니다. 그것은 얻을 수있는 것만큼이나 나쁘다.

것을 명심 std공간이 많은 것이 식별자의 톤이 매우 일반적인 것들 (생각 list, sort, string, iterator, 너무 다른 코드에 표시 할 가능성이 높다 등).

이것이 가능성이 없다고 생각하는 경우 : 이 대답을 준 지 약 반년 후에 거의 정확히 이런 일이 발생한 (누락 된 접두사 로 인해 잘못된 함수가 호출 된) Stack Overflow에 대한 질문 이있었습니다 std::. 다음 은 그러한 질문에 대한 또 다른 최근의 예입니다. 그래서 이것은 진짜 문제입니다.


여기에 또 하나의 데이터 포인트가 있습니다. 수년 전에는 표준 라이브러리의 모든 것을 접두사로 지정해야하는 불편 함을 발견했습니다 std::. 그런 다음 처음 using에 함수 범위를 제외하고 지시문과 선언이 모두 금지되어 있다고 결정한 프로젝트에서 작업했습니다 . 뭔지 맞춰봐? 접두사를 쓰는 데 익숙해지는 데는 거의 몇 주가 걸렸고 몇 주 후에 우리 대부분은 실제로 코드를 더 읽기 쉽게 만드는 데 동의했습니다 . 그 이유가 있습니다. 짧은 산문을 좋아하든 긴 산문을 좋아하든 주관적이지만 접두사는 객관적으로 코드에 명확성을 추가합니다. 컴파일러뿐만 아니라 사용자도 참조되는 식별자를 쉽게 확인할 수 있습니다.

10 년 동안이 프로젝트는 수백만 줄의 코드로 성장했습니다. 이러한 논의가 계속해서 나오기 때문에 using프로젝트에서 실제로 (허용 된) 함수 범위 가 얼마나 자주 사용되는지 궁금 했습니다. 나는 그것에 대한 출처를 파악했고 그것이 사용 된 곳을 한두 곳만 찾았다. 나에게 이것은 한 번 시도하면 개발자가 std::사용이 허용 된 곳에서도 100kLoC마다 한 번이라도 사용 지시문을 사용하기에 충분히 고통스럽지 않다는 것을 나타냅니다 .


결론 : 모든 것에 명시 적으로 접두사를 붙이는 것은 아무런 해를 끼치 지 않으며 익숙해지는 데 거의 걸리지 않으며 객관적인 이점이 있습니다. 특히 컴파일러와 사람이 읽는 사람이 코드를 더 쉽게 해석 할 수 있도록합니다. 이는 코드 작성시 주요 목표가 될 것입니다.

453 ChrisW Sep 21 2009 at 10:22

using namespace클래스의 헤더 파일을 넣을 때의 문제는 클래스를 사용하려는 사람 (헤더 파일을 포함하여)이 다른 네임 스페이스를 '사용'(즉, 모든 것을 확인)하도록 강요한다는 것입니다.

그러나 (비공개) * .cpp 파일에 using 문을 자유롭게 넣을 수 있습니다.


하지만 때문에 - 어떤 사람들은 내이 같은 "자유로운 느낌"말에 동의하지 않는 것을주의 usingCPP 파일에 문이 더 나은 헤더보다 (그것이 당신의 헤더 파일을 포함 사람들에 영향을 미치지 않기 때문에), 그들이 그것을 아직도 생각 좋습니다 (코드에 따라 클래스 구현을 유지하기가 더 어려울 수 있기 때문입니다). 이 C ++ Super-FAQ 항목에 따르면

using-directive는 레거시 C ++ 코드와 네임 스페이스로의 전환을 용이하게하기 위해 존재하지만, 최소한 새 C ++ 코드에서는 사용하지 않아야합니다.

FAQ는 두 가지 대안을 제안합니다.

  • 사용 선언 :

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • std ::

    std::cout << "Values:";
    
241 DavidThornley Oct 29 2010 at 00:37

최근에 Visual Studio 2010 에 대한 불만이 있었습니다. 거의 모든 소스 파일에 다음 두 줄이 있음이 밝혀졌습니다.

using namespace std;
using namespace boost;

많은 Boost 기능이 C ++ 0x 표준에 포함되고 Visual Studio 2010에는 많은 C ++ 0x 기능이 있으므로 갑자기 이러한 프로그램이 컴파일되지 않았습니다.

따라서 피하는 using namespace X;것은 미래 보장의 한 형태이며, 사용중인 라이브러리 및 / 또는 헤더 파일을 변경해도 프로그램이 손상되지 않도록하는 방법입니다.

216 mattnewport Nov 04 2014 at 03:00

짧은 버전 : using헤더 파일에 전역 선언이나 지시문을 사용하지 마십시오 . 구현 파일에서 자유롭게 사용하십시오. Herb Sutter 와 Andrei Alexandrescu 가 C ++ 코딩 표준 에서이 문제에 대해 말한 내용은 다음과 같습니다 (강조를 위해 굵은 글씨로 표시).

요약

네임 스페이스 사용은 다른 사람에게 가하는 것이 아니라 편의를위한 것입니다. #include 지시문 앞에 using 선언이나 using 지시문을 작성하지 마십시오.

결과 : 헤더 파일에서 지시문이나 선언을 사용하여 네임 스페이스 수준을 작성하지 마십시오. 대신 모든 이름을 명시 적으로 네임 스페이스 한정합니다. (두 번째 규칙은 첫 번째 규칙을 따릅니다. 헤더는 다른 헤더 #include가 그 뒤에 나타날 수있는 것을 알 수 없기 때문입니다.)

토론

간단히 말해서, #include 지시문 다음에 구현 파일에서 선언과 지시문을 자유롭게 사용하여 네임 스페이스를 사용할 수 있고 사용해야합니다. 반대로 반복되는 주장에도 불구하고, 선언과 지시문을 사용하는 네임 스페이스는 악의가 없으며 네임 스페이스의 목적을 무효화하지 않습니다. 오히려 네임 스페이스를 사용 가능하게 만듭니다 .

128 robson3.14 Sep 21 2009 at 22:47

using특히 헤더에서 전역 범위에서 지시문을 사용해서는 안됩니다 . 그러나 헤더 파일에서도 적절한 상황이 있습니다.

template <typename FloatType> inline
FloatType compute_something(FloatType x)
{
    using namespace std; // No problem since scope is limited
    return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4));
}

이것은 더 짧고 사용자 정의 부동 소수점 유형 (ADL ( 인수 종속 조회)을 통해)으로 작업 할 수 있기 때문에 명시 적 제한 ( std::sin, std::cos...) 보다 낫습니다 .

100 towi Jan 18 2013 at 16:34

전 세계적으로 사용하지 마십시오.

전 세계적으로 사용될 때만 "나쁜"것으로 간주 됩니다 . 때문에:

  • 프로그래밍중인 네임 스페이스를 복잡하게 만듭니다.
  • 독자는 using namespace xyz.
  • 소스 코드의 다른 독자들에게 사실이 무엇이든간에 가장 자주 읽는 독자 인 자신에게는 더욱 사실입니다. 1 ~ 2 년 후에 돌아와서 살펴보세요 ...
  • 당신에 대해 이야기 만한 using namespace std다면 당신이 잡은 모든 것을 알지 못할 수도 있고, 다른 것을 추가 #include하거나 새로운 C ++ 개정판으로 이동할 때 당신이 알지 못했던 이름 충돌이 발생할 수 있습니다.

로컬에서 사용할 수 있습니다.

계속해서 로컬에서 (거의) 자유롭게 사용하십시오. 물론 이것은 당신이 반복하는 것을 방지 std::하고 반복도 나쁘다.

로컬에서 사용하기위한 관용구

C ++ 03에는 swap클래스를위한 함수를 구현하기위한 관용구 (상용구 코드)가있었습니다 . 실제로 로컬을 사용 using namespace std하거나 적어도 using std::swap다음을 사용하는 것이 좋습니다 .

class Thing {
    int    value_;
    Child  child_;
public:
    // ...
    friend void swap(Thing &a, Thing &b);
};
void swap(Thing &a, Thing &b) {
    using namespace std;      // make `std::swap` available
    // swap all members
    swap(a.value_, b.value_); // `std::stwap(int, int)`
    swap(a.child_, b.child_); // `swap(Child&,Child&)` or `std::swap(...)`
}

이것은 다음과 같은 마술을합니다.

  • 컴파일러는 std::swapfor value_, 즉 void std::swap(int, int).
  • 오버로드가 void swap(Child&, Child&)구현 된 경우 컴파일러가이를 선택합니다.
  • 당신이 경우 하지 가 과부하가 컴파일러 사용 void std::swap(Child&,Child&)이러한 교환 최선을 시도합니다.

C ++ 11에서는이 패턴을 더 이상 사용할 이유가 없습니다. 의 구현은 std::swap잠재적 인 과부하를 찾아서 선택하도록 변경되었습니다.

81 sth Sep 21 2009 at 10:23

당신이 바로 그 헤더 파일을 가져 오는 경우 갑자기 같은 이름이 hex, left, plus또는 count글로벌 범위를. std::이러한 이름 이 포함되어 있는지 알지 못하는 경우 놀랄 수 있습니다 . 이러한 이름을 로컬에서도 사용하려고하면 꽤 혼란 스러울 수 있습니다.

모든 표준 항목이 자체 네임 스페이스에있는 경우 코드 또는 다른 라이브러리와의 이름 충돌에 대해 걱정할 필요가 없습니다.

52 MartinBeckett Sep 21 2009 at 10:13

또 다른 이유는 놀라움입니다.

내가 본다면 cout << blah, std::cout << blah내 생각 대신 : 이것은 무엇입니까 cout? 정상 cout입니까? 특별한가요?

49 AlexanderPoluektov Mar 29 2011 at 15:10

숙련 된 프로그래머는 문제를 해결하는 모든 것을 사용하고 새로운 문제를 생성하는 것을 피하며 정확한 이유 때문에 헤더 파일 수준의 사용 지시문을 피합니다.

숙련 된 프로그래머는 소스 파일 내에서 이름의 완전한 규정을 피하려고합니다. 이에 대한 사소한 이유 는 합당한 이유가없는 한 적은 코드로 충분할 때 더 많은 코드를 작성하는 것이 우아하지 않기 때문 입니다. 이에 대한 주된 이유는 ADL (인수 종속 조회)을 해제하기 때문입니다.

이러한 좋은 이유 는 무엇입니까 ? 때로는 프로그래머가 명시 적으로 ADL을 끄고 싶을 때도 있고 명확하게하고 싶을 때도 있습니다.

따라서 다음은 괜찮습니다.

  1. 함수 구현 내부의 함수 수준 사용 지시문 및 사용 선언
  2. 소스 파일 내부의 소스 파일 수준 사용 선언
  3. (때때로) 소스 파일 레벨 사용 지시문
46 Oleksiy Aug 29 2013 at 16:44

나는 전 세계적으로 사용해서는 안된다는 데 동의하지만 namespace. 다음은 "The C ++ Programming Language"의 예입니다 .

namespace My_lib {

    using namespace His_lib; // Everything from His_lib
    using namespace Her_lib; // Everything from Her_lib

    using His_lib::String; // Resolve potential clash in favor of His_lib
    using Her_lib::Vector; // Resolve potential clash in favor of Her_lib

}

이 예에서는 구성으로 인해 발생할 수있는 잠재적 인 이름 충돌 및 모호성을 해결했습니다.

거기에서 명시 적으로 선언 된 이름 (같은 using-declarations로 선언 된 이름 포함 His_lib::String)은 using-directive ( using namespace Her_lib)에 의해 다른 범위에서 액세스 가능한 이름보다 우선 합니다.

32 Yelonek Sep 21 2009 at 16:34

나는 또한 그것을 나쁜 습관이라고 생각합니다. 왜? 언젠가는 네임 스페이스의 기능이 물건을 나누는 것이라고 생각했기 때문에 모든 것을 하나의 글로벌 백에 넣는 것으로 망쳐서는 안됩니다.

그러나 'cout'과 'cin'을 자주 사용하는 경우 using std::cout; using std::cin;.cpp 파일에 다음 과 같이 씁니다 (으로 전파 될 때 헤더 파일에는 사용하지 않음 #include). 나는 제정신이 스트림 cout이나 cin. ;)

27 gnasher729 Mar 14 2014 at 00:22

코드를보고 무엇을하는지 아는 것이 좋습니다. 내가 본다면 그것이 도서관 std::coutcout흐름 임을 압니다 std. 내가 본다면 나는 cout모른다. 도서관 의 흐름 이 될 수 있습니다 . 또는 동일한 기능에서 10 줄 더 높을 수 있습니다 . 또는 해당 파일에 이름이 지정된 변수 . 무엇이든 될 수 있습니다.coutstdint cout = 0;staticcout

이제 특별히 크지 않은 백만 줄의 코드베이스를 가져 와서 버그를 찾고 있습니다. 즉,이 100 만 줄에서해야 할 일을 수행하지 않는 한 줄이 있다는 것을 알고 있습니다. 명명 된을 cout << 1;읽고 왼쪽으로 1 비트 이동 한 다음 결과를 버릴 수 있습니다. 버그를 찾으면 확인해야합니다. 내가 정말로보고 싶어하는 것을 알 수 있습니까?static intcoutstd::cout

당신이 교사이고 생계를 위해 어떤 코드도 작성하고 유지할 필요가 없었다면 정말 좋은 생각처럼 보이는 것 중 하나입니다. 나는 코드를 보는 것을 좋아합니다. 그리고 (2) 나는 그것을 쓰는 사람이 그것이 무엇을하는지 알고 있다고 확신합니다.

25 PreetSangha Sep 21 2009 at 10:14

복잡성 관리에 관한 것입니다. 네임 스페이스를 사용하면 원하지 않는 항목을 끌어 올 수 있으므로 디버깅하기가 더 어려워 질 수 있습니다. std ::를 사용하면 모든 곳에서 읽기가 더 어렵습니다 (더 많은 텍스트와 모든 것).

코스 용 말-자신이 가장 잘 할 수 있고 느끼는 방식으로 복잡성을 관리합니다.

20 RonWarholic Sep 21 2009 at 10:19

중히 여기다

// myHeader.h
#include <sstream>
using namespace std;


// someoneElses.cpp/h
#include "myHeader.h"

class stringstream {  // Uh oh
};

이것은 간단한 예입니다. 20 개의 포함 및 기타 가져 오기가있는 파일이있는 경우 문제를 파악하기 위해 거쳐야하는 많은 종속성이 있습니다. 더 나쁜 것은 충돌하는 정의에 따라 다른 모듈에서 관련없는 오류가 발생할 수 있다는 것입니다.

끔찍하지는 않지만 헤더 파일이나 글로벌 네임 스페이스에서 사용하지 않으면 두통을 덜 수 있습니다. 매우 제한된 범위에서 수행하는 것이 좋습니다. 그러나 내 함수의 출처를 명확히하기 위해 추가로 5 개의 문자를 입력하는 데 문제가 없었습니다.

19 Kevin Sep 03 2016 at 03:06

우려를 명확히하는 구체적인 예입니다. 당신은 당신이 두 개의 라이브러리가 상황을 상상 foo하고 bar, 자신의 네임 스페이스와 각 :

namespace foo {
    void a(float) { /* Does something */ }
}

namespace bar {
    ...
}

이제 다음과 같이 자신의 프로그램에서 foobar함께 사용한다고 가정 해 보겠습니다 .

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

이 시점에서 모든 것이 정상입니다. 프로그램을 실행하면 'Does something'. 그러나 나중에 업데이트 bar하고 다음과 같이 변경되었다고 가정 해 보겠습니다.

namespace bar {
    void a(float) { /* Does something completely different */ }
}

이 시점에서 컴파일러 오류가 발생합니다.

using namespace foo;
using namespace bar;

void main() {
    a(42);  // error: call to 'a' is ambiguous, should be foo::a(42)
}

따라서 'a'가 의미하는 바를 명확히하기 위해 약간의 유지 관리 작업을 수행해야합니다 foo::a. 이는 바람직하지 않지만 다행히도 매우 쉽습니다 ( 컴파일러가 모호하다고 표시하는 foo::모든 호출 앞에 추가하기 만하면 a됩니다).

그러나 대신 막대가 다음과 같이 변경된 대체 시나리오를 상상해보십시오.

namespace bar {
    void a(int) { /* Does something completely different */ }
}

이 시점에서 당신의 전화 a(42)에 갑자기 바인딩 bar::a대신 foo::a대신 '뭔가'가 않는 '완전히 다른 무언가를'일을. 컴파일러 경고 또는 아무것도 없습니다. 프로그램은 이전과는 완전히 다른 작업을 조용히 시작합니다.

네임 스페이스를 사용할 때 이와 같은 시나리오가 발생할 위험이 있으므로 사람들이 네임 스페이스를 사용하는 것을 불편하게합니다. 네임 스페이스에있는 항목이 많을수록 충돌의 위험이 커지므로 사람들은 std다른 네임 스페이스보다 네임 스페이스를 사용하는 것이 훨씬 더 불편할 수 있습니다 (해당 네임 스페이스의 항목 수가 많기 때문).

궁극적으로 이것은 쓰기 가능성과 신뢰성 / 유지 보수 가능성 사이의 균형입니다. 가독성도 고려할 수 있지만 어느 쪽이든 그에 대한 주장을 볼 수 있습니다. 일반적으로 안정성과 유지 관리가 더 중요하다고 말하지만이 경우에는 상당히 드문 안정성 / 유지 관리 효과에 대해 쓰기 비용을 지속적으로 지불하게됩니다. '최상의'절충안은 프로젝트와 우선 순위를 결정합니다.

18 user2645752 Nov 09 2013 at 22:09

동시에 많은 네임 스페이스를 사용하는 것은 분명히 재난의 비결이지만, JUST 네임 스페이스 std와 네임 스페이스 만 사용 std하는 것은 내 생각에 그렇게 큰 문제가 아닙니다. 재정의는 자신의 코드에 의해서만 발생할 수 있기 때문입니다.

따라서 "int"또는 "class"와 같은 예약 된 이름으로 기능하는 것으로 간주하면됩니다.

사람들은 그것에 대해 너무 항문 적이 지 않아야합니다. 선생님은 계속 옳았습니다. 하나의 네임 스페이스 만 사용하십시오. 이것이 바로 네임 스페이스 사용의 요점입니다. 동시에 하나 이상을 사용해서는 안됩니다. 당신 자신이 아니라면. 다시 말하지만 재정의는 일어나지 않을 것입니다.

18 DustinGetz Sep 21 2009 at 11:04
  1. 당신과 다른 스타일과 모범 사례 의견을 가진 사람들이 작성한 코드를 읽을 수 있어야합니다.

  2. 만 사용하는 cout경우 아무도 혼동하지 않습니다. 그러나 많은 네임 스페이스가 날아 다니고이 클래스를보고 그것이 무엇을하는지 정확히 알 수없는 경우 네임 스페이스를 명시 적으로 사용하는 것이 일종의 주석 역할을합니다. "오, 이것은 파일 시스템 작업입니다"또는 "네트워크 작업을 수행하고 있습니다."라는 것을 한 눈에 볼 수 있습니다.

14 Carl Feb 12 2015 at 07:40

나는 여기에있는 다른 사람들의 의견에 동의하지만, 가독성에 관한 문제를 해결하고 싶습니다. 파일, 함수 또는 클래스 선언의 맨 위에있는 typedef를 사용하여 모든 것을 피할 수 있습니다.

클래스의 메서드는 유사한 데이터 유형 (멤버)을 처리하는 경향이 있고 typedef는 클래스 컨텍스트에서 의미있는 이름을 할당 할 수있는 기회이므로 일반적으로 클래스 선언에서 사용합니다. 이것은 실제로 클래스 메소드의 정의에서 가독성을 돕습니다.

// Header
class File
{
   typedef std::vector<std::string> Lines;
   Lines ReadLines();
}

그리고 구현에서 :

// .cpp
Lines File::ReadLines()
{
    Lines lines;
    // Get them...
    return lines;
}

반대로 :

// .cpp
vector<string> File::ReadLines()
{
    vector<string> lines;
    // Get them...
    return lines;
}

또는:

// .cpp
std::vector<std::string> File::ReadLines()
{
    std::vector<std::string> lines;
    // Get them...
    return lines;
}
14 RohanSingh Apr 05 2015 at 19:56

네임 스페이스는 명명 된 범위입니다. 네임 스페이스는 관련 선언을 그룹화하고 개별 항목을 별도로 유지하는 데 사용됩니다. 예를 들어, 별도로 개발 된 두 개의 라이브러리는 서로 다른 항목을 참조하기 위해 동일한 이름을 사용할 수 있지만 사용자는 두 가지를 모두 사용할 수 있습니다.

namespace Mylib{
    template<class T> class Stack{ /* ... */ };
    // ...
}

namespace Yourlib{
    class Stack{ /* ... */ };
    // ...
}

void f(int max) {
    Mylib::Stack<int> s1(max); // Use my stack
    Yourlib::Stack    s2(max); // Use your stack
    // ...
}

네임 스페이스 이름을 반복하면 독자와 작성자 모두에게주의가 산만해질 수 있습니다. 결과적으로 특정 네임 스페이스의 이름은 명시 적 제한없이 사용할 수 있음을 나타낼 수 있습니다. 예를 들면 :

void f(int max) {
    using namespace Mylib; // Make names from Mylib accessible
    Stack<int> s1(max); // Use my stack
    Yourlib::Stack s2(max); // Use your stack
    // ...
}

네임 스페이스는 서로 다른 라이브러리 및 서로 다른 코드 버전을 관리하기위한 강력한 도구를 제공합니다. 특히, 그들은 비 로컬 이름에 대한 참조를 만드는 방법에 대한 프로그래머 대안을 제공합니다.

출처 : Bjarne Stroustrup 의 C ++ 프로그래밍 언어 개요

11 Nithin Dec 31 2014 at 15:00

using namespace std알고리즘 라이브러리의 함수이기도 한 개수의 모호성으로 인해 컴파일 오류가 발생 하는 예 입니다.

#include <iostream>
#include <algorithm>

using namespace std;

int count = 1;
int main() {
    cout << count << endl;
}
10 CryogenicNeo Apr 24 2018 at 00:15

소프트웨어 나 프로젝트 성능이 나빠지지는 않습니다. 소스 코드 시작 부분에 네임 스페이스를 포함하는 것은 나쁘지 않습니다. using namespace std지침 의 포함 여부는 귀하의 필요와 소프트웨어 또는 프로젝트를 개발하는 방식에 따라 다릅니다.

namespace stdC ++ 표준 함수와 변수를 포함합니다. 이 네임 스페이스는 C ++ 표준 함수를 자주 사용할 때 유용합니다.

이 페이지 에서 언급 한 바와 같이 :

네임 스페이스 std를 사용하는 문은 일반적으로 나쁜 습관으로 간주됩니다. 이 문에 대한 대안은 형식을 선언 할 때마다 범위 연산자 (: :)를 사용하여 식별자가 속한 네임 스페이스를 지정하는 것입니다.

그리고이 의견을보십시오 :

네임 스페이스를 많이 사용하고 아무것도 충돌하지 않는지 확인하는 경우 소스 파일에서 "using namespace std"를 사용하는 데 문제가 없습니다.

일부 사람들은 using namespace std모든 함수와 변수를 해당 네임 스페이스에서 호출하기 때문에 소스 파일에 를 포함하는 것이 좋지 않다고 말했습니다 . 에 포함 된 다른 함수와 동일한 이름의 새 함수를 정의 namespace std하려는 경우 함수에 오버로드가 발생하고 컴파일 또는 실행으로 인해 문제가 발생할 수 있습니다. 예상대로 컴파일되거나 실행되지 않습니다.

이 페이지 에서 언급 한 바와 같이 :

이 명령문은 std ::를 입력하지 않아도되지만 std 네임 스페이스에 정의 된 클래스 또는 유형에 액세스하려고 할 때마다 std 네임 스페이스 전체를 프로그램의 현재 네임 스페이스로 가져옵니다. 이것이 왜 그렇게 좋지 않을 수 있는지 이해하기 위해 몇 가지 예를 들어 보겠습니다.

...

이제 개발의 후반 단계에서 "foo"라는 라이브러리에서 사용자 정의 구현 된 다른 버전의 cout을 사용하려고합니다 (예 :

...

cout이 가리키는 라이브러리가 모호하다는 점에 유의하십시오. 컴파일러는 이것을 감지하고 프로그램을 컴파일하지 않을 수 있습니다. 최악의 경우, 식별자가 속한 네임 스페이스를 지정하지 않았기 때문에 프로그램은 여전히 ​​컴파일되지만 잘못된 함수를 호출 할 수 있습니다.

8 Dr.Watson Sep 21 2009 at 10:34

모든 조건에서 반드시 나쁜 습관이라고 생각하지는 않지만 사용할 때주의해야합니다. 라이브러리를 작성하는 경우 네임 스페이스와 함께 범위 확인 연산자를 사용하여 라이브러리가 다른 라이브러리와 충돌하지 않도록해야합니다. 응용 프로그램 수준 코드의 경우 잘못된 것이 없습니다.

8 Noname Oct 14 2014 at 00:30

나는 다른 사람들의 의견에 동의합니다 – 그것은 이름 충돌, 모호성을 요구하고 있으며 사실은 덜 명확합니다. 의 사용을 볼 수는 있지만 using개인적 선호는 제한하는 것입니다. 나는 또한 다른 사람들이 지적한 것을 강력하게 고려할 것입니다.

상당히 일반적인 이름 일 수있는 함수 이름을 찾고 싶지만 std네임 스페이스 에서만 찾으려면 (또는 그 반대 -namespace , namespace , ...에 없는 모든 호출을 변경하려는 경우 ), 그럼 어떻게 할 것을 제안합니까?stdX

이를 수행하는 프로그램을 작성할 수 있지만 프로젝트를 유지 관리하는 프로그램을 작성하는 것보다 프로젝트 자체에 시간을 보내는 것이 더 낫지 않습니까?

개인적으로 저는 std::접두사를 신경 쓰지 않습니다 . 나는 그것을 가지고 있지 않은 것보다 외모를 더 좋아합니다. 그것이 명시 적이기 때문인지 "이것은 내 코드가 아닙니다. 표준 라이브러리를 사용하고 있습니다."라고 말하거나 다른 것이 있는지는 모르겠지만 더 멋져 보인다고 생각합니다. 최근에야 C ++에 들어갔다는 점을 감안할 때 이상 할 수 있습니다 (더 오래 C와 다른 언어를 사용하고 여전히 사용하고 있으며 C는 어셈블리 바로 위에서 가장 좋아하는 언어입니다).

위와 다른 사람들이 지적하는 것과 다소 관련이 있지만 다른 것이 있습니다. 이것은 나쁜 관행 일 수 있지만 때로는 std::name프로그램 별 구현을 위해 표준 라이브러리 버전과 이름을 예약 합니다. 예, 실제로 이것은 당신을 물고 당신을 세게 물릴 수 있지만,이 모든 것은 제가이 프로젝트를 처음부터 시작했고, 저는 그것에 대한 유일한 프로그래머입니다. 예 : 나는 오버로드 std::string하고 그것을이라고 부릅니다 string. 도움이되는 추가 사항이 있습니다. 소문자 이름에 대한 C 및 Unix (+ Linux) 경향 때문에 부분적으로 수행했습니다.

그 외에도 네임 스페이스 별칭을 사용할 수 있습니다. 여기에 언급되지 않았을 수있는 유용한 경우의 예가 있습니다. 저는 C ++ 11 표준을 사용하고 특히 libstdc ++와 함께 사용합니다. 글쎄, 그것은 완전한 std::regex지원 이 없습니다 . 물론 컴파일되지만 프로그래머 쪽에서 오류 인 줄을 따라 예외가 발생합니다. 그러나 구현이 부족합니다.

그래서 여기에 내가 그것을 해결 한 방법이 있습니다. Boost의 정규식을 설치하고 연결합니다. 그런 다음 libstdc ++가 완전히 구현할 때이 블록 만 제거하면 코드가 동일하게 유지되도록 다음을 수행합니다.

namespace std
{
    using boost::regex;
    using boost::regex_error;
    using boost::regex_replace;
    using boost::regex_search;
    using boost::regex_match;
    using boost::smatch;
    namespace regex_constants = boost::regex_constants;
}

나는 그것이 나쁜 생각인지 아닌지에 대해 논쟁하지 않을 것입니다. 그러나 나는 그것이 프로젝트를 위해 깨끗하게 유지 하고 동시에 그것을 구체적으로 만든다고 주장 할 것이다 . 사실, 나는 Boost를 사용해야 하지만 libstdc ++가 결국 그것을 가질 것처럼 그것을 사용하고있다. 예, 자신의 프로젝트를 시작하고 처음부터 표준 (...)으로 시작하면 유지 관리, 개발 및 프로젝트와 관련된 모든 것을 돕는 데 큰 도움이됩니다!

명확하게하기 위해 : STL 에서 클래스 이름을 사용하는 것이 실제로는 좋은 생각이 아니라고 생각합니다 . 문자열은 내가 '문자열'이라는 아이디어가 마음에 들지 않았기 때문에 예외입니다 (첫 번째, 위 또는 두 번째는 무시하십시오. 필요한 경우 말장난).

그대로, 나는 여전히 C에 편향되어 있고 C ++에 편향되어 있습니다. 세부 사항을 절약하고 내가 작업하는 대부분은 C에 더 적합합니다 (하지만 그것은 좋은 연습이었고 나 자신을 만드는 좋은 방법이었습니다 a. 다른 언어를 배우고 b. 객체 / 클래스 / 등에 대해 덜 편향되지 않도록 노력하십시오. 덜 폐쇄적이고, 덜 오만하고, 더 많이 받아들입니다.). 하지만 입니다 내가 수행하는 경우 이름 충돌을 야기 두 가지 이름을 (같은 것) 종류 I 실제로 목록을 사용 않으며, (그것은 매우 일반적인하지가 있습니까?) : 유용한 것은 일부는 이미 제안 것입니다 using namespace std;, 그래서를 이를 위해 저는 구체적이고 통제력이 있으며 표준 용도로 사용하려는 경우이를 지정해야한다는 것을 알고 있습니다. 간단히 말해서, 가정이 허용되지 않습니다.

그리고 Boost의 정규식을 std. 나는 미래의 통합을 위해 그렇게하고 – 다시 말하지만, 이것이 편견이라는 것을 완전히 인정합니다 – 나는 그것이 boost::regex:: .... 사실 그것은 저에게 또 다른 일입니다. C ++에는 아직 룩스와 메소드에서 완전히 받아들이지 못한 많은 것들이 있습니다 (또 다른 예 : 가변 템플릿 대 var 인수 [하지만 가변 템플릿은 매우 유용합니다!]). 내가 비록 그 것을 어렵게했다 동의 나는 여전히 그들과 함께 문제가 있습니다.

8 EngineDev Aug 21 2016 at 05:55

내 경험에 따르면을 사용하는 여러 라이브러리가 cout있지만 다른 목적으로 잘못된 cout.

예를 들어, 내가 입력하는 경우 using namespace std;using namespace otherlib;그냥 입력 cout하는 대신, (둘 다 될 일이있는) std::cout(또는 'otherlib::cout'), 당신은 잘못 하나를 사용하고, 오류를 얻을 수 있습니다. 사용하는 것이 훨씬 더 효과적이고 효율적 std::cout입니다.

8 SwissFrank May 23 2019 at 05:05

경우에 따라 다릅니다. 소프트웨어 수명 기간 동안 소프트웨어의 "총 소유 비용"을 최소화하려고합니다. "using namespace std"라고 말하면 약간의 비용이 들지만 이를 사용 하지 않으면 가독성이 떨어집니다.

사람들은 그것을 사용할 때 표준 라이브러리가 새로운 기호와 정의를 도입하면 코드 컴파일이 중단되고 변수 이름을 변경해야 할 수 있다고 올바르게 지적합니다. 그러나 이것은 아마도 좋은 장기적 일 것입니다. 왜냐하면 당신이 놀라운 목적을 위해 키워드를 사용한다면 미래의 유지 관리자들이 순간적으로 혼란 스럽거나 산만해질 것이기 때문입니다.

당신은하지 않습니다 싶어 다른 사람에 의해 알려진 벡터없는 말, 벡터라는 템플릿을 가지고. 그리고 이렇게 C ++ 라이브러리에 도입 된 새로운 정의의 수는 충분히 적어 단순히 나오지 않을 수도 있습니다. 이 변화 이런 종류의 작업을 수행하는 데에 비용은하지만, 비용이 높은되지 않고 사용하지 않음으로써 얻을 수있는 선명도에 의해 상쇄되어 std다른 용도로 기호 이름을.

클래스, 변수 및 함수의 수를 감안할 때 std::모든 항목에 대해 언급 하면 코드가 50 %까지 부풀려지고 머리를 돌리기가 더 어려워집니다. 한 화면의 코드에 적용 할 수있는 방법의 알고리즘 또는 단계는 이제 앞뒤로 스크롤해야합니다. 이것은 실제 비용입니다. 비용이 많이 들지는 않을지 모르지만 그것이 존재한다고 부인하는 사람들은 경험이 없거나 독단적이거나 단순히 잘못되었습니다.

다음 규칙을 제공합니다.

  1. std다른 모든 라이브러리와 다릅니다. 기본적으로 모두가 알아야 할 하나의 라이브러리이며, 제 생각에는 언어의 일부로 생각하는 것이 가장 좋습니다. 일반적으로 using namespace std다른 도서관이 없더라도 훌륭한 사례 가 있습니다.

  2. 컴파일 단위 (.cpp 파일)의 작성자에게 이것을 using헤더 에 넣어 강제로 결정하지 마십시오 . 항상 편집 단위 작성자에게 결정을 미루십시오. using namespace std모든 곳 에서 사용하기로 결정한 프로젝트에서도 해당 규칙에 대한 예외로 가장 잘 처리되는 몇 가지 모듈 을 사용할 수 있습니다.

  3. 네임 스페이스 기능을 사용하면 심볼이 동일하게 정의 된 많은 모듈을 가질 수 있지만 그렇게하는 것은 혼란 스러울 것입니다. 이름은 가능한 한 다르게 유지하십시오. 네임 스페이스 기능을 사용하지 않더라도라는 클래스가 있고라는 클래스 foostd도입 한 경우 foo어쨌든 클래스 이름을 바꾸는 것이 장기적으로 더 좋습니다.

  4. 네임 스페이스 사용에 대한 대안은 수동으로 네임 스페이스 기호에 접두사를 추가하는 것입니다. 저는 수십 년 동안 두 개의 라이브러리를 사용했는데, 둘 다 C 라이브러리로 시작했습니다. 실제로 모든 기호는 "AK"또는 "SCWin"접두사가 붙습니다. 일반적으로 이것은 "using"구문을 피하는 것과 같지만 쌍 콜론을 작성하지 않습니다. AK::foo()대신 AKFoo()입니다. 이는 코드를 5-10 % 더 조밀하고 덜 장황하게 만듭니다. 유일한 단점은 접두사가 동일한 두 개의 라이브러리를 사용해야하는 경우 큰 문제가 될 수 있다는 것입니다. X Window 라이브러리는 몇 가지 #defines를 사용하여 수행하는 것을 잊은 점을 제외하고는 탁월합니다. TRUE 및 FALSE는 XTRUE 및 XFALSE 여야하며, 이는 마찬가지로 TRUE 및 FALSE를 사용하는 Sybase 또는 Oracle과 네임 스페이스 충돌을 설정했습니다. 다른 가치로! (데이터베이스의 경우 ASCII 0과 1!) 이것의 특별한 이점 중 하나는 전 처리기 정의에 거의 적용 되지 않는 반면 C ++ using/ namespace시스템은이를 처리하지 않는다는 것입니다. 이것의 좋은 이점은 프로젝트의 일부가되는 것에서 결국 도서관이되는 유기적 인 경사를 준다는 것입니다. 내 대규모 응용 프로그램에서 모든 창 클래스는 접두사 Win, 모든 신호 처리 모듈 Mod 등이 있습니다. 이들 중 어느 것도 재사용 될 가능성이 거의 없기 때문에 각 그룹을 라이브러리로 만드는 데 실질적인 이점이 없지만 프로젝트가 어떻게 하위 프로젝트로 나뉘는지 몇 초 안에 분명하게됩니다.

7 AugustKarlstrom Apr 11 2013 at 21:22

정규화되지 않은 가져온 식별자를 사용하면 식별자가 선언 된 위치를 찾으려면 grep 과 같은 외부 검색 도구가 필요합니다 . 이것은 프로그램 정확성에 대한 추론을 어렵게 만듭니다.

7 MathGladiator Sep 21 2009 at 10:15

위치에 따라 다릅니다. 공통 헤더 인 경우 전역 네임 스페이스에 병합하여 네임 스페이스의 값을 줄입니다. 이것은 모듈 전역을 만드는 깔끔한 방법이 될 수 있음을 명심하십시오.

7 adn.911 Nov 30 2017 at 23:24

이것은 종종 글로벌 네임 스페이스 오염으로 알려진 나쁜 습관입니다. 둘 이상의 네임 스페이스에 서명이있는 동일한 함수 이름이있을 때 문제가 발생할 수 있으며, 컴파일러가 호출 할 것을 결정하는 것이 모호 할 수 있으며이 모든 것은 함수 호출로 네임 스페이스를 지정할 때 피할 수 있습니다 std::cout. 도움이 되었기를 바랍니다. :)

6 NoneyoGetit Jun 28 2013 at 03:33

귀하의 질문에 대답하기 위해 실제로 이런 식으로 살펴 봅니다. 많은 프로그래머 (모두는 아님)가 네임 스페이스 std를 호출합니다. 따라서 std 네임 스페이스에있는 것과 동일한 이름을 방해하거나 사용하는 것을 사용하지 않는 습관을 가져야합니다. 그것은 많은 것을 허용하지만 엄격하게 말할 수있는 가능한 일관된 단어와 가명에 비하면 그다지 많지 않습니다.

내 말은 ... "이 존재에 의존하지 말라"는 말은 단지 존재하지 않는 것에 의존하도록 설정하는 것입니다. 코드 스 니펫을 빌리고 지속적으로 수리하는 데 끊임없이 문제가 발생합니다. 사용자 정의 및 차용 한 항목을 제한된 범위로 유지하고 전역을 매우 절약해야합니다 (정직하게 전역은 "지금 컴파일, 나중에 온전함"을 위해 거의 항상 마지막 수단이어야합니다). std를 사용하는 것은 "cout"과 "std :: cout"모두에서 작동하지만 std를 사용하지 않는 것은 "std :: cout"에서만 작동하기 때문에 선생님의 나쁜 조언이라고 생각합니다. 항상 자신의 코드를 모두 작성할만큼 운이 좋은 것은 아닙니다.

참고 : 컴파일러의 작동 방식에 대해 실제로 조금 배울 때까지 효율성 문제에 너무 집중하지 마십시오. 코딩 경험이 조금 있으면 좋은 코드를 단순한 것으로 일반화 할 수있는 정도를 깨닫기 전에 그에 대해 많이 배울 필요가 없습니다. 모든 것을 C로 작성한 것처럼 간단합니다. 좋은 코드는 필요한만큼만 복잡합니다.