“네임 스페이스 std를 사용하는 이유”; 나쁜 연습으로 간주?


2640

나는 쓰는 것을 다른 사람에 의해 들었다 using namespace std;코드에서하는 것은 잘못이다, 내가 사용해야 std::cout하고 std::cin직접 대신.

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


512
"std :: cout;"을 사용하는 것을 잊지 마십시오. 이는 std :: cout을 입력 할 필요는 없지만 전체 std 네임 스페이스를 동시에 가져 오지는 않음을 의미합니다.
Bill

2
@a 유료 nerd google-styleguide.googlecode.com/svn/trunk/… 링크가 더 이상 작동하지 않습니다. 새 링크는 google.github.io/styleguide/cppguide.html#Other_C++_Features
MCG

64
헤더 파일의 파일 범위에서 '네임 스페이스 std 사용'을 사용하는 것은 특히 나쁩니다. 모든 포함 후에 파일 범위에서 소스 파일 (* .cpp)에 사용하는 것은 그 효과가 단일 변환 단위로 제한되므로 그리 나쁘지는 않습니다. 그 효과는 함수 또는 클래스 범위로 제한되므로 함수 나 클래스 내에서 문제를 사용하는 것이 훨씬 덜 문제입니다.
sh-

5
나는 지시어를 사용하여 사용 억제하지만 특정 네임 스페이스 원하는에 대한 것 std::literals::chrono_literals, Poco::Data:Keywords, Poco::Units및 리터럴 또는 가독성 트릭을 처리합니다 물건. 헤더 또는 구현 파일에있을 때마다. 내가 생각하는 함수 범위에서는 괜찮을지 모르지만 리터럴과 물건을 제외하고는 유용하지 않습니다.
Ludovic Zenohate Lagouardette

7
@ 존 : 특히 네임 스페이스 std와 관련이 없습니다. 나의 강조는 "헤더 파일의 파일 범위에서"라는 의미였다. 이를 조언으로하려면 : 헤더 파일의 파일 범위에서 "사용 네임 스페이스"(std 또는 기타)를 사용하지 마십시오. 구현 파일에서 사용하는 것이 좋습니다. 애매하게해서 죄송합니다.
sh-

답변:


2230

이것은 성능과 전혀 관련이 없습니다. 그러나 이것을 고려하십시오 : 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()이 아닌 이벤트했을 것이다.


435
나는 항상 파이썬의 "big_honkin_name을 bhn로 가져 오기"를 좋아했기 때문에 "big_honkin_name.something"대신 "bhn.something"을 사용할 수 있습니다. 실제로 타이핑을 줄입니다. C ++에는 이와 같은 것이 있습니까?
paxdiablo 2018 년

764
@Pax 네임 스페이스 io = boost :: filesystem;
AraK September

152
"수정하려는 노력"이라고 말하는 것이 과장되어 있다고 생각합니다. 새로운 foo :: Quux의 인스턴스가 없으므로 bar :: Quux를 사용하여 현재 사용하는 모든 것을 명확하게하십시오.
MattyT

289
현명한 사람이 정규화되지 않은 이름이 표준 유형과 충돌하는 유형의 라이브러리를 작성합니까?
erikkallen

94
@TomA : 문제 #define는 네임 스페이스로 제한되지 않지만 전체 코드베이스를 가로 지르는 것 입니다. 네임 스페이스 별칭은 원하는 것입니다.
sbi

1391

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

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

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

이 가능성을 고려 경우가 있었다 질문 물었다 거의 정확히이 (인해 생략에라는 잘못된 기능 일어난 곳 스택 오버플로 여기에 std::나는이 대답을 준 후 반년에 대한 접두사). 다음은 이러한 질문의 또 다른, 더 최근의 예이다. 따라서 이것은 실제 문제입니다.


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

10 년 동안이 프로젝트는 수백만 줄의 코드로 성장했습니다. 이러한 논의가 계속 반복되기 때문에 (허용 된) 함수 범위가 using실제로 프로젝트에서 얼마나 자주 사용되는지 궁금 했습니다. 나는 그 소스를 grep하고 그것이 사용 된 한두 곳에서만 발견했다. 나에게 이것은 일단 시도하면 개발자가 std::100 kLoC마다 지시문을 사용할 수있는 곳에서도 지시문을 사용할 정도로 고통스럽지 않다는 것을 나타냅니다 .


결론 : 모든 접두사를 명시 적으로 사용하면 아무런 해를 끼치 지 않으며 익숙해지기가 거의 없으며 객관적인 이점이 있습니다. 특히, 컴파일러와 독자가 코드를 쉽게 해석 할 수있게 해주므로 코드 작성시 주요 목표가되어야합니다.


140
한 줄로 묶을 수있는 코드 밀도에 큰 영향을줍니다. 당신은 매우 긴 방법으로 코드를 작성하게됩니다. 가독성이 떨어집니다. 개인적으로, 나는 더 짧은 (그러나 너무 짧지는 않은) 코드는 더 읽기 쉬운 경향이 있다고 생각합니다 (읽을 물건이 적고 방해가되는 물건이 적기 때문에).
Lie Ryan

91
C ++에 표준 string클래스 가 있기 전에 옛날에 놓친 것 같고 모든 라이브러리에 고유 한 라이브러리가있는 것 같습니다. 설명 :로 코드 작성을 계속 std::하고 코드를 grep -v std:: | vim탐색 할 때 코드를 실행할 수 있습니다 . 또는 std::배경색과 같은 색으로 지정되는 키워드 인 편집기를 가르 칠 수 있습니다 . 뭐든간에
Mike DeSimone

79
나는 전혀 std::해롭지 않다고 생각 합니다. 매우 중요한 정보를 제공합니다 (즉, "뒤에 오는 것은 표준 라이브러리의 일부입니다"). 여전히 짧고 간결한 접두어입니다. 대부분 문제가 전혀 없습니다. 때로는 몇 줄의 코드가 있습니다. std네임 스페이스 에서 특정 기호를 많이 참조해야하는 경우 using해당 특정 범위 의 문은 문제를 훌륭하게 해결하지만 일반적으로 소음이 아니며 모호성을 제거하는 것 외에도 귀중한 정보 전달 합니다.
jalf

146
내가 볼 때마다 std::, 나는 그것을 std::생각할 필요가 없다는 것을 알고 있습니다. 내가 볼 경우 stringlist또는 map그 자체로, 나는 조금 궁금합니다.
Mateen Ulhaq

67
@LieRyan 그리고 지금 뭔가 이름을 지정하지 않고 기하 라이브러리를 작성 행운 vector, transform또는 distance. 그리고 그것들은 표준 라이브러리에서 사용되는 많은 공통 이름 의 예일뿐입니다 . C ++의 필수 부분 인 네임 스페이스 기능에 대한 두려움이나 편견을 사용하지 말라고 제안하는 것은 오히려 비생산적입니다.
Christian Rau

420

using namespace클래스의 헤더 파일을 넣을 때의 문제는 클래스를 사용하려는 사람 (헤더 파일 포함)을 다른 네임 스페이스에서도 '사용'(즉, 모든 것을 볼 수 있도록)해야한다는 것입니다.

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


일부 사람들 using은 cpp 파일 의 문장 이 헤더보다 낫지 만 (헤더 파일을 포함하는 사람들에게 영향을 미치지 않기 때문에) 여전히 내 생각에 동의하지 않는다는 점에주의하십시오 . 코드에 따라 클래스 구현을 유지하기가 더 어려울 수 있기 때문에 좋습니다 . 이 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:";

1
물론 누군가가 std : cout << std :: hex를 가지고 std :: restore_cout_state에 실패하지 않도록 전역 cout의 상태를 가정해서는 안됩니다. 그러나 그것은 완전히 다른 fatberg입니다.
Móż

233

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

using namespace std;
using namespace boost;

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

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


14
이. 부스트는이 표준과 많은 중복을 - 특히 11 ++ C 때문이다.
einpoklum

1
나는 한 번 그렇게하고 어려운 교훈을 배웠습니다. 이제는 using함수 정의 외부 using namespace에서 사용하지 않으며 거의 ​​사용하지 않습니다 .
Ferruccio

210

짧은 버전 : using헤더 파일에 전역 선언이나 지시문을 사용하지 마십시오 . 구현 파일에서 자유롭게 사용하십시오. Herb SutterAndrei AlexandrescuC ++ 코딩 표준 에서이 문제에 대해 말한 내용은 다음과 같습니다 (강조를위한 대담은 내 것입니다).

요약

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

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

토론

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


4
그냥 한 번 더 프로그래머의 의견 여기에,하지만 난 단어가 그 문으로 100 % 동의하면서 using헤더에 표시해서는 안됩니다 장소에 무료 라이센스에 대한 확신으로, 나는 아니에요 using namespace xyz;특히, 코드에서 아무 곳 xyz입니다 std. 내가 사용 using std::vector;하는 경우에만 때문에 충돌의 훨씬 덜 위험을 선도, 의사를 전역으로 네임 스페이스에서 하나의 요소를 가져옵니다 때문에 양식을.
dgnuff

2
궤도에서 @Lightness Races는 물론 귀하의 의견에 대한 권리가 있습니다. 이 답변에 제공된 조언에 동의하지 않는 이유를 설명하려고 시도한 경우 더 도움이 되었습니까? 네임 스페이스의 '사용'이 나쁜 경우 네임 스페이스의 요점을 이해하는 것이 특히 흥미로울까요? std :: cout 대신 std_cout이라는 이름을 지정하지 않는 이유는 무엇입니까?
nyholku

1
@ nyholku : 필요 없음-다른 답변의 대부분은 내가 똑같은 이유를 제공합니다. 또한 내 의견에 ":)"를 적어주십시오. 그리고 나는 네임 스페이스가 나쁘다고 말하지 않았습니다.
궤도에서 가벼움 레이스

예, 나는 주목했습니다 :) 그러나 IMO (이 현인 조언에 위배되는) 대다수의 답변은 잘못 인도되었습니다 (현재 대다수의 통계를 만들지 않았습니다). 네임 스페이스가 '나쁘지 않다'는 데 동의하면이 답변에 동의하지 않을 경우 적절한 위치라고 말할 수 있습니다.
nyholku

나는 도울 수 없지만 using namespace악한 것처럼 악 하다고 느낀다 goto. 둘 다 유효하게 사용되지만 1000 중에서 999 번 잘못 사용됩니다. 따라서 using namespace소스에서 다른 포함의 네임 스페이스를 깔끔하게 오염시키지 않습니다. 그러나 여전히으로부터 보호하지 않습니다 "재미" 에서 발생 using namespace Foo+ using namespace Bar당신이 (호출 암시 푸에 : :) baz(xyz)) 및 관련 변경없이 갑자기 코드 차단 (해서 때문에 Bar::baz()단지 더 나은 될 일이 추가 곳을 얻었다 일치 (따라서 이제 대신 호출됩니다)
CharonX

122

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));
}

이는 명시 적 규정 ( std::sin, std::cos...) 보다 낫습니다 (ADL ( 인수 종속 조회 )을 통해).


9
미안하지만 이것에 강력히 동의하지 않습니다.
Billy ONeal

4
@Billy : userlib :: cos (userlib :: superint) 호출을 지원하는 다른 방법은 없습니다. 모든 기능에는 용도가 있습니다.
Zan Lynx

17
@ 잔 : 물론 있습니다. using std::cos;,, using std::sin등. 문제는 잘 디자인 된 userlib것은 자체 네임 스페이스 를 가지고 sin있고 cos내부 공간 을 가질 것이므로 실제로 도움이되지 않습니다. ( using namespace userlib이 템플릿 앞에는 using namespace std없고 범위가 제한되지 않는 한 범위가 제한되지 않습니다.) 또한, 이와 같은 유일한 기능은 swap입니다. 그런 경우에는 템플릿을 만드는 것이 좋습니다. std::swap전체 문제의 전문화 및 회피.
Billy ONeal

11
@BillyONeal : template<typename T> void swap(MyContainer<T>&, MyContainer<T>&)(FTPS (function template partial specialization)가 없으므로 대신 오버로드를 사용해야합니다.
sbi

38
@BillyONeal : 귀하의 (7 배 찬성!) 의견이 잘못 되었습니다. 귀하가 설명하는 상황은 ADL이 다루기 위해 정확히 설계된 상황 입니다. 요약하면, 만약 x갖는 하나 이상의 "연관된 네임 스페이스"(예를 들어 그것의 정의 된 경우 namespace userlib)처럼 보이는 것을 다음 모든 함수 호출 cos(x)한다 별도로 네임 스페이스에서 볼 - 않고 모든 using namespace userlib;필요한 미리 존재한다. Zan Lynx가 옳다 (그리고 C ++ 이름 조회는 비잔틴이다 ...)
j_random_hacker

97

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

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

  • 프로그래밍하고있는 네임 스페이스를 복잡하게 만듭니다.
  • 많은을 사용할 때 독자는 특정 식별자의 출처를 알기가 어렵습니다 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::swap를 들어 value_, 즉 void std::swap(int, int).
  • 과부하가 void swap(Child&, Child&)구현 된 경우 컴파일러에서이를 선택합니다.
  • 당신이 경우 하지 가 과부하가 컴파일러 사용 void std::swap(Child&,Child&)이러한 교환 최선을 시도합니다.

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


5
"std :: swap의 구현이 잠재적 인 과부하를 찾아서 선택하도록 변경되었습니다." - 뭐? 확실합니까? swapC ++ 11에서는 처음에 사용자 정의를 제공하는 것이 더 이상 중요하지 않다는 것이 사실이지만 , std::swap그 자체가 더 유연하기 때문에 (이동 의미를 사용합니다). 그러나 std::swap나만의 새로운 커스텀 스왑을 자동으로 선택하십시오. (그리고 나는 그것을 정말로 믿지 않습니다).
Christian Rau

@ChristianRau 나는 그렇게 생각합니다. 나는 이것을 어딘가에서 읽었습니다. 우리는 항상 Howard 에게 물어볼 수 있습니다 . 나는 파고파고 ... 지금
towi

14
스왑의 경우에도보다 명확한 (그리고 고맙게도) 관용구는 using std::swap;보다는 쓰기를 하는 것 using namespace std;입니다. 보다 구체적인 관용구는 부작용이 적으므로 코드를 유지 관리하기가 더 쉽습니다.
Adrian McCarthy

11
마지막 문장이 잘못되었습니다. C ++ 11에서 Std Swap Two Step 은 공식적 으로 전화 하는 올바른 방법 으로 축복을 받았으며 swap표준의 다른 여러 곳에서 전화를 걸도록 변경되었습니다 swap(위에서 언급 한 바와 같이 NB using std::swap가 아닌 올바른 방법입니다 using namespace std). 그러나 std::swap그 자체는 다른 것을 찾아서 사용 하도록 강조 되지 않았습니다swap . 경우 std::swap호출되는 다음 std::swap사용됩니다.
Jonathan Wakely

3
using std::swap자체 문서화 코드를 작성하는 동시에 로컬 네임 스페이스를 줄이려면 로컬로 입력하는 것이 현명 할 수 있습니다 . std 네임 스페이스 전체에 거의 관심이 없으므로 관심있는 부분을 선택하십시오.
Lundin

79

당신이 바로 그 헤더 파일을 가져 오는 경우 갑자기 같은 이름이 hex, left, plus또는 count글로벌 범위를. std::이러한 이름 이 포함되어있는 것을 모르는 경우 놀라운 결과 일 수 있습니다 . 이 이름을 로컬로 사용하려고하면 혼란이 생길 ​​수 있습니다.

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


12
하나는 말할 것도없고 distance. 여전히 나는 가독성을 높이기 때문에 실질적으로 가능한 경우 정규화되지 않은 이름을 선호합니다. 또한, 나는 우리가 보통 구두로 말해서 자격을 갖추지 못하고 가능한 모호성을 해결하는 데 기꺼이 시간을 보내고 있다는 사실, 자격없이 말하고있는 것을 이해하고 소스에 적용 할 가치가 있음을 의미합니다. 코드는 자격이 없어도 모든 것이 무엇인지 분명하게 알 수 있도록 구조화되어 있음을 의미합니다.
건배와 hth. -Alf

그러나 공정하게 말하면 포함하지 않으면 대부분이 없습니다 <iomanip>. 그래도 좋은 지적입니다.
einpoklum

48

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

만약 내가 보는 cout << blah대신에, std::cout << blah나는 이것이 무엇이라고 생각 cout합니까? 정상 cout입니까? 뭔가 특별한가요?


25
지금 농담하는 거지? 나는 진정으로 말할 수 없다. 그렇지 않다면 개인적으로 코드를 믿지 않는 한 그것이 정상적인 '통화'라고 가정합니다. 그렇지 않으면 BEYOND MAJOR 코드 냄새, IMO 일 것입니다. ... 그리고 코드를 믿지 않으면 왜 처음에 코드를 사용합니까? 나는 "신뢰하는 진실"이라고 말하고 있지 않습니다. 그러나 이것은 GitHub의 유명한 라이브러리 또는 다른 것을 다루는 경우 약간 가져 오는 것 같습니다.
브렌트 리튼 하우스

28
@BrentRittenhouse cout는 모두가 인식하기 때문에 나쁜 예입니다. 그러나 future금융 앱에서 상상해보십시오 . 지정된 날짜에 물건을 사고 파는 계약입니까? 아닙니다. 코드가 말하면 std::future쉽게 혼동되지 않을 것입니다.
James Hollis

2
@BrentRittenhouse는 약간 나쁜 예일 수 있습니다. 적어도 4 개의 다른 라이브러리가 있습니다. "표준 라이브러리입니까? libstdc ++? stl? 다른 것입니까?" 그리고 모든 사람이 std :: cout을 아는 것은 아닙니다. 최소한 기본적으로 우리가받는 7 명 중 6 명은 그렇지 않습니다. 교육 과정은 교육 과정을 사용하지 않기 때문입니다. printfs를 쫓아 내야합니다. 또는 Qt에서 디버그 ().
스위프트-금요일 파이

1
정말? C ++에 대한 많은 수의 책 sooo의 첫 번째 장의 첫 번째 예에서 (삽입 연산자 사용법이있는) 것이 일부 새로운 이사회가 알고 있는 유일한 C ++ 인 경우와 거의 같습니다 .
mckenzm

@mckenzm 난잡함을 줄이기 위해 책이나 강의 노트에 넣을 수도 있지만 코드는 아닙니다.
Martin Beckett

45

숙련 된 프로그래머는 문제를 해결하기 위해 무엇이든 사용하고 새로운 문제를 일으키는 것은 피하고 정확한 이유 때문에 헤더 파일 수준의 지시문을 사용하지 않습니다.

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

좋은 이유 는 무엇입니까 ? 때로는 프로그래머가 명확하게 ADL을 끄고 싶거나 다른 경우에는 명확하게하기를 원합니다.

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

  1. 함수 구현 내에서 함수 레벨 사용 지시문 및 사용 선언
  2. 소스 파일 내 소스 파일 레벨 사용 선언
  3. (때로는) 소스 파일 수준 using 지시문

43

전 세계적으로 사용해서는 안된다는 데 동의하지만, 에서처럼 로컬에서 사용하는 것은 그렇게 나쁘지 않습니다 namespace. 다음은 "C ++ 프로그래밍 언어"의 예입니다 .

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-declaration으로 선언 된 이름 포함 His_lib::String)은 using-directive ( using namespace Her_lib)에 의해 다른 범위에서 액세스 가능한 이름보다 우선 합니다.


29

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

그러나 'cout'과 'cin'을 자주 사용하는 경우 using std::cout; using std::cin;.cpp 파일에 다음 과 같이 씁니다 (헤더 파일에는으로 전파되지 않습니다 #include). 나는 아무도 제정신 이제까지 스트림 이름없는 것이라고 생각 coutcin. ;)


7
이것은 로컬 using 선언 이며 using 지시문 과는 매우 다릅니다 .
sbi

25

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

이제 백만 줄 코드베이스를 취하십시오. 특히 크지 않은 버그를 찾고 있습니다.이 백만 줄에 한 줄이 있다는 것을 알고 있음을 의미합니다. named을 cout << 1;읽고 1 비트 왼쪽으로 시프트 한 다음 결과를 버릴 수 있습니다. 버그를 찾으려면 확인해야합니다. 내가 정말로보고 싶은 것을 어떻게 알 수 있습니까 ?static intcoutstd::cout

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


4
"std :: cout << 1"이 std 네임 스페이스에서 cout이라는 정적 int를 읽지 않고 그것을 하나만 바꾸고 결과를 버리는 것을 어떻게 알 수 있습니까? 또한 "<<"가 무엇을하는지 어떻게 알 수 있습니까;) ??? ...이 답변은 '사용'을 피하기에 좋은 데이터 포인트가 아닌 것 같습니다.
nyholku

4
누군가 std :: cout을 정수로 재정의했다면 문제는 기술적이지 않지만 사회적입니다. 누군가가 당신을 위해 그것을 가지고 있습니다. (그리고 아마도 #define true false 등과 같은 것들에 대해서도 모든 헤더를 확인해야합니다)
Jeremy Friesner

2
cout을 볼 때 항상 std :: cout이라는 것을 알고 있습니다. 내가 틀렸다면, 내가 아닌이 코드를 작성한 사람의 문제입니다. :)
Tien Do

22

복잡성을 관리하는 것이 전부입니다. 네임 스페이스를 사용하면 원하지 않는 것들을 끌어 들일 수 있으므로 디버그하기가 더 어려워집니다 (가능하다고 말합니다). std :: 사용 : 모든 곳에서 읽기가 더 어렵습니다 (텍스트와 그 이상).

코스를위한 말-최선을 다하고 능력을 발휘하는 방법으로 복잡성을 관리하십시오.


18

치다

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


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

class stringstream {  // Uh oh
};

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

끔찍한 것은 아니지만 헤더 파일이나 전역 네임 스페이스에서 두통을 사용하지 않으면 두통을 피할 수 있습니다. 매우 제한된 범위 에서이 작업을 수행하는 것이 좋을 수도 있지만 함수의 출처를 명확히하기 위해 추가로 5자를 입력하는 데 아무런 문제가 없었습니다.


18
  1. 스타일과 모범 사례 의견이 다른 사람들이 작성한 코드를 읽을 수 있어야합니다.

  2. 을 사용하는 cout경우 아무도 혼란스럽지 않습니다. 그러나 많은 네임 스페이스가 날고 있고이 클래스를 볼 때 클래스가 무엇인지 정확히 알지 못하면 명시 적 네임 스페이스가 일종의 주석으로 작동합니다. 언뜻보기에 "오, 이것은 파일 시스템 작업입니다"또는 "네트워크 작업을하고 있습니다"입니다.


17

많은 네임 스페이스를 동시에 사용하는 것은 분명히 재난의 요리법이지만 JUST 네임 스페이스 std와 네임 스페이스 만 사용 std하는 것은 재정의가 자신의 코드에 의해서만 발생할 수 있기 때문에 내 의견으로는 그다지 중요하지 않습니다 ...

"int"또는 "class"와 같은 예약 된 이름으로 기능을 고려하면됩니다.

사람들은 그것에 대해 너무 항문 적이 지 않아야합니다. 선생님이 잘 지내셨습니다. 하나의 네임 스페이스 만 사용하십시오. 그것이 네임 스페이스를 처음 사용하는 요점입니다. 동시에 둘 이상을 사용해서는 안됩니다. 그것이 당신의 것이 아닌 한. 다시 정의하면 다시 정의되지 않습니다.


짧은 문자열 좋아 - 충돌을 만들기 하드가 아닌 min, end그리고 less에 나타납니다 std::네임 스페이스. 그러나 이제 std::수천 개의 기호가 포함되어 있기 때문에 독자가 알지 못하는 새로운 기호의 출처를 아는 것이 유용합니다.
Tom Swirly

std 네임 스페이스는 사용자, 동료 또는 사용자가 사용하는 미들웨어를 작성하는 사람들이 항상 네임 스페이스 내에 함수를 배치하는 데 현명하지는 않기 때문에 존재합니다. 따라서 std :: min과 std :: min 및 std :: min과 다른 사람의 레거시 :: min () 사이의 충돌을 std ::
Aiken Drum

14

나는 다른 사람들과 동의하지만 가독성과 관련된 문제를 해결하고 싶습니다. 파일, 함수 또는 클래스 선언 맨 위에 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;
}

typedef가 유용하지만 typedef를 사용하는 대신 Lines를 나타내는 클래스를 만드는 것이 좋습니다.
Eyal Solnik

14

우려를 명확히하는 구체적인 예. 두 개의 라이브러리가 foo있고 bar각각 고유 한 네임 스페이스 가있는 상황이 있다고 상상해보십시오 .

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

namespace bar {
    ...
}

이제 당신이 사용하는 가정 해 봅시다 foo하고 bar다음과 같이 자신의 프로그램에 함께 :

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

이 시점에서 모든 것이 정상입니다. 프로그램을 실행할 때 '무언가를한다'. 그러나 나중에 업데이트 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다른 네임 스페이스보다 네임 스페이스를 사용하는 것이 더 불편할 수 있습니다 (해당 네임 스페이스의 항목 수로 인해).

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


두 번째 시나리오는 거래를 성사시킵니다. 네임 스페이스가 다시 없습니다. 기능상 미묘한 변화는 감지 할 수 없습니다.
safe_malloc

13

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

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 ++ 프로그래밍 언어 개요


4
그는 C ++에이 기능을 도입 할 때 비얀 스트로브 스트 룹이 얻은 것을 다른에서지도를 기반으로하는이 대답은 -2 ... 소년 비얀은 가난하고 미숙 한 프로그래머 틀림 매우 흥미로운
nyholku

@nyholku : 이것을보십시오 .
sbi

10

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

#include <iostream>

using namespace std;

int count = 1;
int main() {
    cout << count << endl;
}

2
::count--문제 해결됨. 일반적으로 std 네임 스페이스에서 다른 것보다 더 많은 것을 얻을 수 있으므로 using namespace 지시문을 잘못 유지하면 입력을 줄일 수 있습니다.
PSkocik

여기서 진짜 문제는 C ++에 여전히 네임 스페이스가없는 전역이 있다는 것입니다. 이 방법과 'this'가 메소드에 암시 적이라는 사실은 올바른 'count'변수를 사용하더라도 너무 많은 버그와 문제를 일으킬 수 없습니다. ;)
Aiken Drum

9

소프트웨어 나 프로젝트 성능을 악화 시키지는 않습니다. 소스 코드 시작 부분에 네임 스페이스를 포함시키는 것은 나쁘지 않습니다. 이 using namespace std지침 의 포함 여부는 요구 사항과 소프트웨어 또는 프로젝트 개발 방식에 따라 다릅니다.

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

페이지 에서 언급했듯이 :

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

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

네임 스페이스를 많이 사용하고 아무 것도 충돌하지 않음을 알고있을 때 소스 파일에서 "네임 스페이스 std 사용"을 사용하는 데 문제가 없습니다.

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

페이지 에서 언급했듯이 :

이 명령문은 std ::를 입력하지 않아도되지만 std 네임 스페이스에 정의 된 클래스 나 유형에 액세스 할 때마다 std 네임 스페이스 전체를 프로그램의 현재 네임 스페이스로 가져옵니다. 왜 이것이 좋지 않은지 이해하기 위해 몇 가지 예를 들어 봅시다.

...

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

...

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


8

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


7

"왜 네임 스페이스 std를 사용하고 있습니까?" "C ++에서 나쁜 습관으로 간주 되었습니까?"

나는 그것을 다른 방식으로 넣었습니다. 왜 5 명의 추가 문자를 입력하면 일부는 번거로운 것으로 간주됩니까?

예를 들어 수치 소프트웨어를 작성하는 것을 고려하십시오. "vector"가 문제 도메인의 가장 중요한 개념 중 하나 일 때 일반 "std :: vector"를 "vector"로 줄임으로써 왜 글로벌 네임 스페이스를 오염시키는 것을 고려할까요?


19
단지 5 개의 추가 문자가 아닙니다. 표준 라이브러리에서 객체 유형을 참조 할 때마다 5 개의 추가 문자가 있습니다. 표준 라이브러리를 많이 사용하는 경우 자주 사용됩니다. 알맞은 크기의 프로그램에 더 현실적으로 수천 개의 추가 문자가 있습니다. 아마도 'using'지시어가 사용되도록 언어에 추가 된 것 같습니다.
Jeremy Friesner

5
매번 5 개의 추가 문자가 아니라 5 개의 문자와 몇 개의 마우스 클릭만으로 메뉴를 풀고 선택한 편집기에서 찾기 및 바꾸기를 수행 할 수 있습니다.
DaveWalley

1
가독성. cout << hex << setw(4) << i << endl;보다 읽기 쉽다std::cout << std::hex << std::setw(4) << i << std::endl;
oz1cz

16
그리고 더 나쁘다 : std::map<std::string,std::pair<std::string,std::string>>에 비해 끔찍하다 map<string,pair<string,string>>.
oz1cz

4
어쨌든 STL 컨테이너를 typedef하는 것이 좋습니다 : std :: 정말로 중요하지 않습니다. 그리고 C ++ 11은 예를 들어 반복자를 사용할 때 훨씬 쉽게 할 수 있도록 auto 키워드를 가져 왔습니다.
juzzlin

7

나는 다른 사람들에게 동의합니다 – 그것은 이름 충돌, 모호성을 요구하고 있습니다. 그리고 사실은 덜 명확합니다. 의 사용을 볼 수는 있지만 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 의 클래스 / 이름을 의도적이고 구체적으로 대신 사용하는 것이 좋은 생각은 아닙니다 . 'String'이라는 아이디어가 마음에 들지 않았으므로 문자열은 예외입니다 (필요한 경우 말장난, 첫 번째, 위 또는 두 번째 무시).

그대로, 나는 여전히 C에 대해 매우 편견이 있으며 C ++에 대해 편견이 있습니다. 세부 사항을 절약하고, 내가 작업하는 많은 부분이 C에 더 적합합니다 (그러나 그것은 좋은 운동이었고 나 자신을 만드는 좋은 방법이었습니다. 덜 닫힌 마음, 덜 거만하고 더 수용 적.). 하지만 입니다 내가 수행하는 경우 이름 충돌을 야기 두 가지 이름을 (같은 것) 종류 I 실제로 목록을 사용 않으며, (그것은 매우 일반적인하지가 있습니까?) : 유용한 것은 일부는 이미 제안 것입니다 using namespace std;, 그래서를 그 목적을 위해 나는 구체적이고 통제력이 있고 표준 사용을 원한다면 그것을 명시해야한다는 것을 알고 있습니다. 간단히 말해서 허용되는 가정은 없습니다.

그리고 Boost의 정규 표현식을의 일부로 만드는 것과 관련하여 std. 향후 통합을 위해이 작업을 수행하고 다시 한 번 이것은 이것이 편견임을 인정 boost::regex:: ...합니다. 그러나 그것이 그렇게 추악하다고 생각하지 않습니다 . 사실, 그것은 저에게 또 다른 것입니다. C ++에는 아직 외모와 메소드에서 아직 완전히 받아들이지 않은 것들이 많이 있습니다 (또 다른 예 : 가변 템플릿과 var 인수 [변형 템플릿은 매우 유용합니다!). 내가 비록 그 것을 어렵게했다 동의 나는 여전히 그들과 함께 문제가 있습니다.


1
std네임 스페이스 확장 은 정의되지 않은 동작 이므로 절대로 수행해서는 안됩니다.
tambre

7

내 경험에 따르면 say를 사용하는 여러 라이브러리가 cout있지만 다른 목적으로 잘못 사용할 수 있습니다 cout.

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


6

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


6

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


6

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


5

귀하의 질문에 대답하기 위해 실제로이 방법을 살펴보십시오. 많은 프로그래머 (모두는 아님)가 네임 스페이스 std를 호출합니다. 따라서 네임 스페이스 std에있는 것과 동일한 이름을 충돌 시키거나 사용하는 것을 사용하지 않는 습관이 있어야합니다. 그것은 엄청나게 부여되었지만 엄격하게 말해서 얻을 수있는 일관된 단어와 가명 수와 비교할 때 그리 많지는 않습니다.

내 말은 ... "현재 존재하는 것에 의존하지 말라"는 말은 존재하지 않는 것에 의존하도록 설정하는 것입니다. 지속적으로 코드 스 니펫을 빌려서 지속적으로 수리하는 데 문제가 있습니다. 사용자 정의 및 빌린 물건을 제한된 범위로 유지하고 전역과 매우 아껴서 사용하십시오 (정직한 세계는 "언제나 나중에 컴파일"하기 위해 거의 항상 최후의 수단이어야합니다). std를 사용하는 것이 "cout"과 "std :: cout"모두에 대해 작동하지만 std를 사용하지 않으면 "std :: cout"에 대해서만 작동하기 때문에 교사의 조언이 좋지 않다고 생각합니다. 자신의 코드를 모두 작성하기에 항상 운이 좋은 것은 아닙니다.

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


유용한 표준 라이브러리 함수를 모르는 사람이 몇 명인지 ( <algorithm>예를 들어 에서 항목을 다시 생성 하는 경우) 같은 사람들이 이러한 식별자를 안정적으로 피할 수 있다고 상상하는 것은 약간의 확장입니다. 자신의 코드를 살펴보고라는 변수 또는 함수가 없다고 말합니다 count. 또는 distance, 또는 log, destroy, launch, visit, beta, sample, messages, clamp, erase, copy, modulus, left, 등으로 아직 모든 식별자를 언급하지 않는 stdC ++ (35)가 나오면 ... 코드를 깰 것
토비 Speight에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.