std 네임 스페이스 사용


110

std 네임 스페이스와 관련하여 '사용'을 사용하는 데 다른 견해가있는 것 같습니다.

어떤 사람들은 ' using namespace std'를 사용한다고 말하고 , 다른 사람들은 ' std::' 와 함께 사용할 std 함수를 접두사로 말하고 다른 사람들은 다음과 같이 사용한다고 말합니다.

using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::vector;

사용할 모든 표준 함수에 대해.

각각의 장단점은 무엇입니까?




답변:


131

대부분의 C ++ 사용자는 아주 만족 읽고 std::string, std::vector원시보고, 사실 등 vector이있는 경우 궁금한데을 std::vector하거나 다른 사용자 정의 vector.

나는 항상 using namespace std;. 모든 종류의 이름을 전역 네임 스페이스로 가져 오며 모든 종류의 명확하지 않은 모호성을 유발할 수 있습니다.

다음은 std네임 스페이스 에있는 몇 가지 일반적인 식별자입니다 . 개수, 정렬, 찾기, 같음, 역방향. 지역 변수라는 데 count의미 using namespace std사용할 수 없습니다 count대신을 std::count.

원치 않는 이름 충돌의 전형적인 예는 다음과 같습니다. 당신이 초보자이고에 대해 모른다고 상상해보십시오 std::count. 다른 것을 사용하고 <algorithm>있거나 관련이없는 것처럼 보이는 헤더에 의해 끌어 온다고 상상해보십시오 .

#include <algorithm>
using namespace std;

int count = 0;

int increment()
{
    return ++count; // error, identifier count is ambiguous
}

std::count일부 긴 중첩 유형이있는 템플릿 이므로 오류는 일반적으로 길고 비 친화적 입니다.

그래도 괜찮 std::count습니다. 글로벌 네임 스페이스로 들어가고 함수 개수가이를 숨기기 때문입니다.

#include <algorithm>
using namespace std;

int increment()
{
    static int count = 0;
    return ++count;
}

약간 놀랍게도 이것은 괜찮습니다. 선언적 범위로 가져온 식별자는 정의 된 위치와 가져온 위치를 모두 포함하는 공통 네임 스페이스에 나타납니다. 즉, std::countcount전역 네임 스페이스에서와 같이 표시 되지만 increment.

#include <algorithm>

int increment()
{
    using namespace std;
    static int count = 0;
    return ++count;
}

그리고 비슷한 이유로 count여기에서 모호합니다. using namespace std발생하지 않습니다 std::count, count예상대로 외부 를 숨 깁니다 . using namespace그 규칙 수단 std::count보이는합니다 (의 increment역할)이 동일한 범위의 전역, 즉에서 선언 된 것처럼 int count = 0;따라서 모호성을 일으키고.

#include <algorithm>

int count = 0;

int increment()
{
    using namespace std;
    return ++count; // error ambiguous
}

21
하지만 std :: 접두사없이 훨씬 쉽게 soooo를 입력 합니다!
xtofl

69
@xtofl : 아니요, 그렇지 않습니다. 5 개의 문자는 입력 할 때 그다지 관련이 없지만이 5 개의 문자는 읽을 때 매우 관련이있을 수 있습니다. 코드는 작성된 것보다 훨씬 더 읽기 때문에 소스 코드의 입력 용이성보다 읽기의 용이성보다 훨씬 더 중요합니다.
sbi

3
using 문이 범위 규칙과 함께 올바르게 작동한다고 추가 할 수 있습니다.
Martin York

2
@Martin York : 범위 지정 규칙을 보여주는 예제로 업데이트되었습니다. @Michael Burr : 틀림없이 그렇게 나쁘지는 않습니다. 제가 정말 싫어하는 것은 단순한 실수에 대한 오류 메시지가 해석하기 훨씬 더 어려워 지거나 전혀 발생하지 않는 곳입니다. 예를 들어, 함수가 범위 내에 있다고 믿지만 그렇지 않고 std :: 함수가 유용한 '식별자 인식되지 않음'오류를 얻는 대신 종종 더 모호한 '인수를 변환 할 수 없음'으로 끝납니다. X '또는'템플릿에서 함수를 생성 할 수 없음 '스타일 오류. 더 나쁜 것은 잘못된 함수가 조용히 호출되는 경우입니다. 드물지만 발생합니다.
CB Bailey

5
글쎄,의 옵션에 대해 아무도 논의하지 않은 것에 놀랐습니다 using std::xxx;. 그것은 짧아집니다 코드를 작성, 네임 스페이스 오염을하지 않고 생각 copy을 많이보다 더 readale입니다 std::copy.
legends2k

41

기본 사항 제외 (모든 stl 객체 / 함수 앞에 std ::를 추가해야하며 'using namespace std'가없는 경우 충돌 가능성이 적음)

절대로 넣어서는 안된다는 점도 주목할 가치가 있습니다.

using namespace std

헤더 파일에서 해당 네임 스페이스를 사용하지 않더라도 해당 헤더 파일을 포함하는 모든 파일에 전파 할 수 있습니다.

어떤 경우에는 다음과 같은 것을 사용하는 것이 매우 유익합니다.

using std::swap

특수한 스왑 버전이있는 것처럼 컴파일러는이를 사용하고 그렇지 않으면 std::swap.

를 호출 std::swap하면 항상 기본 버전을 사용하며 최적화 된 버전 (존재하는 경우)을 호출하지 않습니다.


10
+1 using std::swap(내가 사용하는 유일한 것).
sbi 2009-08-12

1
u n s전파 할 수 있음을 언급하면 ​​+1 . 올바르게 구성된 헤더에 침입 할 수도 있다는 점에 유의하십시오. 악성 헤더 뒤에 포함되어야합니다.
quamrana

1
당신이 정의하는 경우 그러나 swapmove(또는 hash, less등) 전문화를, 당신은으로 그 전문성을 가하고해야한다 namespace std어쨌든. 예 :namespace std {template<> class hash<X> {public: size_t operator()(const X&) const};} class X: {friend size_t std::hash<X>::operator()(const X&)};
AJMansfield

28

첫째, 몇 가지 용어 :

  • using-declaration : using std::vector;
  • 지시어 사용 : using namespace std;

헤더 파일의 전역 범위에서 사용되지 않는 한 using-directives 를 사용 하는 것이 좋습니다. 그래서

using namespace std;

.cpp 파일에있는 것은 실제로 문제가되지 않으며, 문제가있는 것으로 밝혀지면 완전히 제어 할 수 있습니다 (원하는 경우 특정 블록으로 범위를 지정할 수도 있음). 수많은 std::한정자로 코드를 어지럽히는 특별한 이유는 없습니다. 단지 시각적 노이즈가됩니다. 그러나 std코드 에서 네임 스페이스 의 전체 이름을 사용하지 않는 경우 지시문을 생략해도 문제가 없습니다. 그것은 팽팽한 것입니다. 지시가 필요하지 않다면 그것을 사용할 필요가 없습니다.

마찬가지로 네임 스페이스의 특정 유형에 대해 몇 가지 using-declaration ( using-directives 대신)을 사용할std 수 있다면 해당 특정 이름 만 현재 네임 스페이스로 가져 오지 말아야 할 이유가 없습니다. 마찬가지로, 단일 using-directive가 트릭을 수행 할 때 25 또는 30 개의 using-declaration을 갖는 것은 미친 짓이고 부기 번거로울 것이라고 생각합니다.

그것은 당신이 항상 있다는 것을 명심하는 것이 좋다 해야한다 사용하여 선언을 사용. Effective C ++, Third Edition에서 Scott Meyers의 "항목 25 : 던지지 않는 스왑에 대한 지원 고려"를 참조하십시오. 일반적인 템플릿 함수가 매개 변수화 된 유형에 대해 '최상의'스왑 메서드를 사용하도록하려면 using-declaration 및 인수 종속 조회 (일명 ADL 또는 Koenig 조회)를 사용해야합니다.

template< typename T >
void foo( T& x, T& y)
{
    using std::swap;     // makes std::swap available in this function

    // do stuff...

    swap( x, y);         // will use a T-specific swap() if it exists,
                         //  otherwise will use std::swap<T>()

    // ...
 }

네임 스페이스를 많이 사용하는 다양한 언어의 공통 관용구를 살펴 봐야한다고 생각합니다. 예를 들어 Java 및 C #은 네임 스페이스를 광범위하게 사용합니다 (C ++보다 더 많이 사용됨). 네임 스페이스 내의 이름이 해당 언어에서 사용되는 가장 일반적인 방법은 using-directive에 해당하는 것과 함께 한꺼번에 현재 범위로 가져 오는 것입니다. 이것은 광범위한 문제를 일으키지 않으며, 문제가되는 몇 번은 정규화 된 이름을 통해 문제의 이름을 처리하거나 별칭을 지정하여 '예외'기준으로 처리됩니다. C ++에서 수행 할 수있는 것처럼.

Herb Sutter와 Andrei Alexandrescu는 "Item 59 : Do n't write namespace usings in a header file or before an #include"of their book, C ++ Coding Standards : 101 Rules, Guidelines, and Best Practices :

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

Stroupstrup은 "The C ++ Programming Language, Third Edition"에서 "글로벌 네임 스페이스를 오염시키지 마십시오"라는 말로 자주 인용됩니다. 그는 실제로 (C.14 [15])라고 말하지만 C.10.1 장에서 다음과 같이 말합니다.

사용 선언은 로컬 영역에 이름을 추가한다. 사용-지시어는 하지 않습니다; 단순히 선언 된 범위에서 액세스 가능한 이름을 렌더링합니다. 예를 들면 :

namespaceX {
    int i , j , k ;
}

int k ;
void f1()
{
    int i = 0 ;

    using namespaceX ; // make names from X accessible

    i++; // local i
    j++; // X::j
    k++; // error: X::k or global k ?

    ::k ++; // the global k

    X::k ++; // X’s k
}

void f2()
{
    int i = 0 ;

    using X::i ; // error: i declared twice in f2()
    using X::j ;
    using X::k ; // hides global k

    i++;
    j++; // X::j
    k++; // X::k
}

로컬로 선언 된 이름 (일반 선언 또는 using-declaration에 의해 선언 됨)은 동일한 이름의 로컬이 아닌 선언을 숨기고 선언 지점에서 이름의 불법적 인 오버로딩이 감지됩니다.

대한 모호성 오류를 참고 k++에서 f1(). 전역 이름은 전역 범위에서 액세스 할 수있는 네임 스페이스의 이름보다 우선하지 않습니다. 이는 우발적 인 이름 충돌에 대한 상당한 보호를 제공하며, 중요한 것은 전역 네임 스페이스를 오염시켜 얻을 수있는 이점이 없음을 보장합니다.

많은 이름을 선언하는 라이브러리가 using-directive를 통해 액세스 가능하도록 만들 때 사용하지 않는 이름의 충돌이 오류로 간주되지 않는다는 것이 중요한 이점입니다.

...

기존의 C 및 C ++ 프로그램에 비해 네임 스페이스를 사용하는 새 프로그램에서 전역 이름 사용이 급격히 줄어들기를 바랍니다. 네임 스페이스에 대한 규칙은 전역 범위를 오염시키지 않도록주의하는 사람보다 전역 이름의``게으른 ''사용자에게 이점을 제공하지 않도록 특별히 제작되었습니다.

그리고 '글로벌 이름의 게으른 사용자'와 같은 이점이있는 이유는 무엇입니까? using-directive를 활용 하여 네임 스페이스의 이름을 현재 범위에서 안전하게 사용할 수 있도록합니다.

std사용 지시문 (뒤에 지시문을 배치하여)을 적절히 사용하여 범위에서 사용할 수 있는 네임 스페이스 의 이름은 전역 네임 스페이스를 오염 #includes시키지 않습니다 . 그 이름을 쉽게 사용할 수 있고 충돌에 대한 지속적인 보호를 제공합니다.


마지막 요점과 관련하여 Java와 C #에는 훨씬 깔끔한 네임 스페이스가 있습니다. BCL의 모든 것이 System에있는 경우 "using System"은 "using namespace std"만큼 많은 문제를 일으킬 수 있습니다.
Jeff Hardy

그러나 내가 보는 Java 및 C # 프로그램은 일반적으로 "시스템"(또는 이에 상응하는 것)뿐만 아니라 사용하는 모든 네임 스페이스를 가져옵니다. 따라서 사용 된 모든 이름을 가져 오는 단일 using 지시문 대신 동일한 작업을 수행하는 5 개 또는 10 개가 있습니다. 또한 "using namespace std;" 정말 그렇게 많은 문제를 일으키나요?
Michael Burr

문제는 std에 너무 많은 공통 이름이 있고 하나의 표준 헤더를 포함하면 다른 모든 헤더가 포함될 수 있다는 것입니다. 수입품에 대한 통제력이 부족하고 위험이 너무 많습니다. Java와 C #에 대해서는 잘 모르지만 C ++보다 훨씬 더 나은 모듈 시스템을 가지고 있고 이름을 가져 오는 것이 일반적으로 눈살을 찌푸리는 Ada에 대해 알고 있습니다. 일반적으로 첫 번째는 명명 규칙의 문제입니다 (나는 사람들이 접두사와 네임 스페이스를 사용하는 것을 보았습니다. 가져 오는 것은 의미가 없습니다).
AProgrammer

1
나는 이것이 실제 문제라는 것을 아직도 확신하지 못합니다. 나는 사용 지시문이 심각한 결점없이 항상 사용되는 것을 본다. 다시 말하지만, 사용 하지 않아도 문제가 없습니다 . std::한정자가 코드를 복잡하게하지 않는 것을 선호합니다. 이를 피할 수있는 다른 방법이 있습니다 (일반적으로 선언 또는 typedef 사용).
Michael Burr

1
@AProgrammer : "list는 lisp 인터프리터에서 목록을 식별하기위한 자연 식별자입니다"라고 말합니다.하지만 " using namespace std;"지시문이 있다고해서 자연 식별자 ' list' 를 선언하는 것을 막을 수는 없습니다. std::list그것을 제한하지 않고 더 오래 사용 하십시오. " using namespace std;"지시문 이없는 경우와 다르지 않습니다 . 아니면 내가 뭔가를 놓치고 있습니까?
Michael Burr

17

헤더 파일의 전역 범위에서 네임 스페이스를 사용하지 마십시오. 이로 인해 충돌이 발생할 수 있으며 충돌이 발생한 파일의 책임자는 원인을 제어 할 수 없습니다.

구현 파일에서 선택은 훨씬 덜 잘립니다.

  • using 네임 스페이스 std를 넣으면 해당 네임 스페이스의 모든 기호를 가져옵니다. 추가 될 기호에 대해 말하지 않고는 거기에있는 모든 기호를 아는 사람이 거의 없기 때문에 (따라서 충돌이없는 정책을 실제로 적용하는 것은 불가능합니다) 문제가 될 수 있습니다. 그리고 C ++ 표준에서는 헤더가 다른 헤더의 기호를 추가 할 수 있습니다 (C에서는 허용하지 않음). 통제 된 케이스에서 쓰기를 단순화하기 위해 실제로는 여전히 잘 작동 할 수 있습니다. 그리고 오류가 발생하면 문제가있는 파일에서이를 감지합니다.

  • std :: name을 사용하여 퍼팅; 알 수없는 기호를 가져올 위험없이 쓰기가 간단하다는 장점이 있습니다. 비용은 원하는 모든 기호를 명시 적으로 가져와야한다는 것입니다.

  • 명시 적으로 자격을 갖추면 약간의 혼란이 더해 지지만 연습 문제가 적다고 생각합니다.

내 프로젝트에서는 모든 이름에 대해 명시 적 자격을 사용하고, std :: name 사용을 수락하고, std 네임 스페이스 사용에 반대합니다 (우리는 자체 목록 유형이있는 lisp 인터프리터가 있으므로 충돌이 확실합니다).

다른 네임 스페이스의 경우 사용되는 명명 규칙도 고려해야합니다. 이름에 네임 스페이스 (버전 관리 용)와 접두사를 사용하는 프로젝트를 알고 있습니다. using namespace Xthen을 수행하는 것은 거의 위험이 없으며 그렇게하지 않으면 코드가 어리석게 보입니다 PrefixNS::pfxMyFunction(...).

기호를 가져 오려는 경우가 있습니다. std :: swap이 가장 일반적인 경우입니다. std :: swap을 가져온 다음 정규화되지 않은 스왑을 사용합니다. 인수 종속 조회는 유형의 네임 스페이스에서 적절한 스왑이있는 경우이를 찾고없는 경우 표준 템플릿으로 대체합니다.


편집하다:

댓글에서 Michael Burr는 충돌이 현실 세계에서 발생하는지 궁금합니다. 여기에 실제 사례가 있습니다. 확장 언어는 lisp 방언입니다. 인터프리터에는 포함 파일 lisp.h가 있습니다.

typedef struct list {} list;

우리는 다음과 같은 코드 ( "엔진"이라고 부를 것입니다)를 통합하고 수정해야했습니다.

#include <list>
...
using std::list;
...
void foo(list const&) {}

그래서 우리는 다음과 같이 수정했습니다.

#include <list>

#include "module.h"
...
using std::list;
...
void foo(list const&) {}

좋은. 모든 것이 작동합니다. 몇 달 후, "module.h"는 "list.h"를 포함하도록 수정되었습니다. 테스트를 통과했습니다. "모듈"은 ABI에 영향을 미치는 방식으로 수정되지 않았으므로 "엔진"라이브러리는 사용자를 다시 컴파일하지 않고도 사용할 수 있습니다. 통합 테스트는 괜찮 았습니다. 새 "모듈"이 게시되었습니다. 코드가 수정되지 않았을 때 엔진의 다음 컴파일이 중단되었습니다.


1
내가 네임 스페이스를 사용할 수 있다고 생각하는 통제 된 사례 중 하나는 코드를 게시하는 것입니다. 단순화는 페이지 레이아웃을 용이하게하고 노출 된 지점에 집중하는 데 도움이됩니다. 단점은 실제로 좋은 연습을 보여주지 않기 때문에 초보자를위한 책에서는 사용하지 않을 것입니다.
AProgrammer

1
std :: 타자를
치는

4
@paoloricardo : 반면에 std :: 모든 곳에 표시되는 것은 불필요한 시각적 혼란입니다.
Michael Burr

1
@Michael : 당신은 당신의 돈을 지불하고 당신의 선택을합니다!
paoloricardo

2
시간을내어 발생한 문제의 세부 정보를 추가해 주셔서 감사합니다.
Michael Burr

4

코드에서 std 및 기타 라이브러리와 이름이 충돌 할 위험이 없다면 다음을 사용할 수 있습니다.

using namespace std;

그러나 문서화에 대한 코드의 종속성을 정확하게 알고 싶거나 이름 충돌의 위험이있는 경우 다른 방법을 사용하십시오.

using std::string;
using std::cout;

세 번째 솔루션은 이러한 솔루션을 사용하지 말고 std :: 코드를 사용할 때마다 더 많은 보안을 제공하지만 코드가 약간 무거울 수 있습니다.


4

양자 모두

using std::string;

using namespace std;

전역 네임 스페이스에 일부 기호 (하나 또는 여러 개)를 추가합니다. 그리고 전역 네임 스페이스에 심볼을 추가 하는 것은 헤더 파일에서 절대로 하지 말아야 할 일입니다. 헤더를 포함 할 사람을 제어 할 수 없으며 다른 헤더를 포함하는 많은 헤더 (및 헤더 등을 포함하는 헤더를 포함하는 헤더 ...)가 있습니다.

구현 (.cpp) 파일에서 그것은 당신에게 달려 있습니다 ( 모든 #include 지시문 후에 해야한다는 것을 기억하십시오 ). 이 특정 파일의 코드 만 분리 할 수 ​​있으므로 이름 충돌의 원인을 관리하고 찾기가 더 쉽습니다. 식별자 앞에 std : :( 또는 다른 접두사, 프로젝트에 많은 네임 스페이스가있을 수 있음)를 선호하는 경우 괜찮습니다. 사용하는 식별자를 전역 네임 스페이스에 추가하고 싶다면 괜찮습니다. 전체 네임 스페이스를 머리에 가져오고 싶다면 :-), 그것은 당신에게 달려 있습니다. 효과는 단일 컴파일 단위로 제한되지만 허용됩니다.


3

저에게는 ::가능 하면 사용하는 것을 선호 합니다.

std::list<int> iList;

나는 쓰기 싫어 :

for(std::list<int>::iterator i = iList.begin(); i != iList.end(); i++)
{
    //
}

바라건대, C ++ 0x를 사용하면 다음과 같이 작성할 수 있습니다.

for(auto i = iList.begin(); i != iList.end(); i++)
{
    //
}

네임 스페이스가 매우 길면

namespace dir = boost::filesystem;

dir::directory_iterator file("e:/boost");
dir::directory_iterator end;

for( ; file != end; file++)
{
    if(dir::is_directory(*file))
        std::cout << *file << std::endl;
}

@AraK : 네임 스페이스 dir = boost :: filesystem; 이게 별명일까요?
paoloricardo

@paoloricardo : 네 그게 뭐야.
sbi

2
반복자는 함께 증가해야 ++i하지, i++이 경우에도 정의 된 경우, 반복자의 불필요한 임시 복사본을 생성하기 때문이다.
Felix Dombek 2011

2

using namespace std헤더의 네임 스페이스 범위에 있으면 안됩니다 . 또한, 나는 그들이 볼 때 궁금해 대부분의 프로그래머를 가정 vector또는 string없이 std::나는 생각하지 않는다, 그래서 using namespace std더 좋다. 그렇기 때문에 나는 결코 존재하지 않는다고 주장 using namespace std합니다.

꼭 필요하다고 생각되면 using std::vector. 그러나 스스로에게 물어보십시오 :이게 무슨 가치가 있는가? 한 줄의 코드는 한 번 (아마도 두 번) 작성되지만 10, 100 또는 수천 번 읽습니다. using 선언 또는 지시문을 추가하는 데 드는 입력 노력은 코드를 읽는 노력에 비해 미미합니다.

이를 염두에두고 10 년 전 프로젝트에서 모든 식별자를 전체 네임 스페이스 이름으로 명시 적으로 한정하기로 결정했습니다. 처음에는 어색해 보였던 것이 2 주 만에 일상이되었습니다. 이제 그 회사 전체의 모든 프로젝트에서 아무도 더 이상 지시문이나 선언을 사용하지 않습니다. (한 가지 예외를 제외하고 아래를 참조하십시오.) 10 년 후 코드 (여러 MLoC)를 살펴보면 올바른 결정을 내린 것 같습니다.

일반적으로 금지에 반대하는 사람들은 using일반적으로 한 프로젝트에 대해 시도하지 않았습니다. 시도한 사람들은 종종 매우 짧은 시간 후에 지시문 / 선언을 사용하는 것보다 더 낫다는 것을 알게됩니다.

참고 : 유일한 예외는 using std::swap(특히 일반 코드에서) 네임 스페이스에 swap()넣을 수없는 오버로드를 선택하는 데 필요한 것입니다 ( 이 네임 스페이스 stdstd함수 오버로드를 넣을 수 없기 때문에 ).


3
std :: swap의 전문화는 완전한 전문화입니다. 함수 템플릿을 부분적으로 전문화 할 수 없습니다. 전문화가 사용자 정의 유형에 의존하는 한 모든 프로그램 표준 라이브러리 템플릿을 부분적으로 전문화 할 수 있습니다.
CB Bailey

@Charles : 네, 맞습니다. 물론 FTPS는 없습니다. 그리고에서 템플릿 을 전문화 할 수 std있지만 과부하는 아닙니다. 그 생각을해서 미안해. 게시물을 수정하겠습니다.
sbi 2009-08-12

2
using namespace지시문 의 의도가 타이핑 을 하는 것이 아니라고 생각합니다 . 오히려 그것은 읽기를 더 쉽게 하기위한 것이 었습니다 . 왜냐하면 당신이 말했듯이 그 코드는 수십, 수백, 수천 번 읽어야 할 것이기 때문입니다. 그리고 어떤 사람들에게는 덜 혼란스럽고 훨씬 쉽게 읽을 수 std::있습니다. 그러나 그것은 아마도 개인적인 지각 능력으로 귀결 될 것입니다. 어떤 사람들은 걸러 std::내거나 안내를 위해 그것을 필요로하고 (예 : 세리프), 다른 사람들은 그 위에 걸터 앉아 울퉁불퉁 한 길에있는 것처럼 느낍니다.
Lumi


1
@sbi : 아니요, 객관적이지 않습니다. std ::가 도움이되는지 아니면 어수선한 지에 따라 다릅니다. 더 클러 터-> 덜 명확합니다.
Joshua Richardson

2

네임 스페이스 는 함수 서명의 혼동오염 을 방지하기 위해 코드를 포함합니다 .

다음적절한 네임 스페이스 사용에 대한 완전하고 문서화 된 데모입니다 .

#include <iostream>
#include <cmath>  // Uses ::log, which would be the log() here if it were not in a namespace, see /programming/11892976/why-is-my-log-in-the-std-namespace

// Silently overrides std::log
//double log(double d) { return 420; }

namespace uniquename {
    using namespace std;  // So we don't have to waste space on std:: when not needed.

    double log(double d) {
        return 42;
    }

    int main() {
        cout << "Our log: " << log(4.2) << endl;
        cout << "Standard log: " << std::log(4.2);
        return 0;
    }
}

// Global wrapper for our contained code.
int main() {
    return uniquename::main();
}

산출:

Our log: 42
Standard log: 1.43508

1

using namespace stdstd현재 네임 스페이스 의 콘텐츠를 가져옵니다 . 따라서 장점은 std::해당 네임 스페이스의 모든 함수 앞에 입력 할 필요가 없다는 것 입니다. 그러나 동일한 이름의 기능을 가진 다른 네임 스페이스가있을 수 있습니다. 따라서 원하는 사람을 부르지 않을 수도 있습니다.

가져올 파일을 수동으로 지정 std하면 그런 일이 발생하지 않지만 파일 시작 부분에 사용 목록이 길어질 수 있으며 일부 개발자는 추악하다고 생각합니다.)!

개인적으로 나는 네임 스페이스가 너무 길 때를 제외하고는 함수를 사용할 때마다 네임 스페이스를 지정하는 것을 선호합니다.이 경우 파일 시작 부분에 using을 추가합니다.

편집 : 다른 답변에서 언급 using namespace했듯이이 헤더를 포함한 모든 파일에 전파되어 원치 않는 동작을 일으킬 수 있으므로 헤더 파일에을 넣지 마십시오.

EDIT2 : Charles 의견 덕분에 내 대답을 수정했습니다.


2
using namespace std;std네임 스페이스 의 내용을 전역 네임 스페이스로 가져옵니다 . 기본 네임 스페이스는 변경되지 않습니다. 전역 네임 스페이스에서 무언가를 정의하는 using namespace std것은 마술처럼 std네임 스페이스에 넣지 않습니다 .
CB Bailey

죄송합니다. 제가 의미 한 것이 아닙니다. 지적 해주셔서 감사합니다. 정정하겠습니다.
Wookai

1
여러분 : 답변 감사합니다. 일반적으로 'using namespace std'를 사용하지 않고 잠재적 인 모호성을 피하는 것이 더 안전합니다. 균형에서 'std :: xxx'를 사용하는 것은 소스 파일의 시작 부분에 다양한 기능 목록을 선언하는 것보다 더 매력적입니다.
paoloricardo

1
따옴표 (네임 스페이스가 너무 긴 경우 제외). 네임 스페이스 별칭을 사용하여 도움을받을 수 있습니다. '네임 스페이스 Rv1 = Thor :: XML :: XPath :: Rules :: Light :: Version1;' 별칭을 기록하고 둘 다 사용 범위 지정 규칙을 따릅니다.
Martin York

0

java.util. *를 포함하거나 단순히 각 클래스를 개별적으로 선택할 수있는 Java와 마찬가지로 스타일에 따라 다릅니다. using namespace std네임 스페이스를 오염시키고 충돌을 일으켜 네임 스페이스의 포인트를 무너 뜨리기 때문에 파일 / 넓은 범위의 시작 부분에 하나 를 원하지 않습니다 . 그러나 STL을 많이 사용하는 함수가있는 경우 논리에 접두사 구문이 뒤죽박죽이되어 코드가 복잡해지며 using namespace std(다양한 클래스를 사용할 때) 또는 개별 usings (몇 가지를 사용할 때 )를 사용하는 것을 고려해야합니다. 수업 자주).


0

이 토론은 작업중인 IDE가 필요한 정확한 정보를 표시하거나 숨길만큼 유연하지 않은 한 계속 진행될 것입니다.

코드의 모양이 현재 작업에 따라 달라지기 때문입니다.

소스 코드를 작성하는 동안 사용중인 클래스를 정확히보고 싶습니다. is it 입니까 std::string, 아니면 BuzFlox::Obs::string클래스입니까?

제어 흐름을 디자인 할 때 변수 유형에 관심이 없지만 if's 및 while's 및 continue's 에 초점을 맞추고 싶습니다 .

그래서 이것은 내 조언입니다.

코드의 대상과 도구의 성능에 따라 가장 쉽게 읽거나 대부분의 정보를 제공하는 방법을 선택하십시오.


0

이를 수정하는 방법에는 여러 가지가 있습니다.

첫째, 당신이 한 것처럼 사용하십시오.

둘째 : do namespace S = std;, 2 개의 문자를 줄입니다.

셋째 : static.

넷째 : 사용하는 이름을 std사용 하지 마십시오 .


-1

각각의 장단점은 무엇입니까

std ::를 생략하는 유일한 이유는 이론적으로 모든 STL 기능을 직접 다시 구현할 수 있기 때문입니다. 그러면 코드를 변경하지 않고 함수를 std :: vector 사용에서 my :: vector로 전환 할 수 있습니다.


네임 스페이스는 실제로는 다르지만 동등한 기능으로 이름을 바꿀 수 있도록 설계되지 않았습니다. 의도하지 않은 이름 충돌을 방지하도록 설계되었습니다.
Michael Burr

예, 그래서 이것을 깨는 'using'지시문의 유일한 이유는 함수를 새 네임 스페이스로 전환 할 수 있도록하는 것입니다.
Martin Beckett

나는 당신이 ass 네임 스페이스의 고통이 무엇인지에 대해 불평하고 using-directive가 없다면 그것들을 창밖으로 버리고 싶어하는 많은 프로그래머들을 발견 할 것이라고 생각한다. 내가 아는 한, 네임 스페이스를 사용하는 모든 언어는 사용 지시어와 비슷한 것을 가지고 있는데, 당신이 원할 때 그들을 방해하지 못하게합니다. 지시문이 쓸모 없다면 왜 어디에나 존재합니까?
Michael Burr

"사용"은 3 자 입력을 저장하는 대신 대체 구현으로 전환 할 수 있도록 의도 된 것이라고 생각합니다. 나는 "std :: Foo"를 사용하는 것을 좋아한다. 그것이 내가 보통의 Foo를 사용하고 있고 그들은 확인할 필요가 없다는 것을 프로그래머와의 계약 역할을하기 때문이다. "com.microsoft.visual-studio.standard-library.numbers.int foo"를 입력 할 필요가 없다는 데 동의합니다. STL의 일부 반복기 선언은 다음과 같습니다. 파이썬은 모듈에서 데코 레이팅되거나 데코 레이팅되지 않은 함수 세트를 가져올 수 있도록하는 좋은 일을합니다.
Martin Beckett

-1

예를 들어

typedef std::vector<int> ints_t;
ints_t ints1;
....
ints_t ints2;

다루기 힘든 대신

std::vector<int> ints1;
...
std::vector<int> ints2;

나는 훨씬 더 읽기 쉽고 코딩에 대한 표준을 발견했습니다.

독자를위한 의미 정보를 포함하는 데 사용할 수도 있습니다. 예를 들어, 함수 프로토 타입을 고려하십시오.

void getHistorgram(std::vector<unsigned int>&, std::vector<unsigned int>&);

반환 값은 무엇입니까?

대신 어때

typedef std::vector<unsigned int> values_t;
typedef std::vector<unsigned int> histogram_t;
...
void getHistogram(values_t&, histogram_t&); 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.