C ++에서`using`을 사용하거나 피합니까? std::string &s) {

ADL로 인해 미묘하게 다른 시맨틱을 할인, 어떻게 일반적으로 사용해야 using하며 왜? 상황에 따라 #include다릅니 까 (예 : 헤더 가 아닌 소스 파일이되는 헤더 )?

또한, ::std::또는 선호 std::합니까?

  1. 네임 스페이스 수준 using namespace:

    using namespace std;
    
    pair<string::const_iterator, string::const_iterator>
    f(const string &s) {
        return make_pair(s.begin(), s.end());
    }
  2. 완전히 명시적임 :

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        return std::make_pair(s.begin(), s.end());
    }
  3. 네임 스페이스 수준의 사용 선언 :

    using std::pair;
    using std::string;
    
    pair<string::const_iterator, string::const_iterator>
    f(const string &s) {
        return make_pair(s.begin(), s.end());
    }
  4. 함수 로컬 사용 선언 :

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        using std::make_pair;
        return make_pair(s.begin(), s.end());
    }
  5. 로컬 기능 using namespace:

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        using namespace std;
        return make_pair(s.begin(), s.end());
    }
  6. 다른 것?

이것은 C ++ 14 이전을 가정하고 있으므로를 사용하여 반환 유형을 공제하지 않습니다 auto.



답변

using네임 스페이스의 목적을 위반하므로 헤더에 사용하지 마십시오 .

소스 파일에서 사용하는 것이 좋지만 일부 경우 (예 🙂 여전히 피할 수 using std있습니다.

그러나 중첩 된 네임 스페이스가 있으면 괜찮습니다.

namespace A {
namespace B {
namespace C {
class s;
} // C
} // B
namespace D{
using B::C::s;
} // D
} // A

답변

소스 파일에 using 문을 넣을 때는 PLEASE를 사용하여 필요한 것을 가져 오십시오. 예를 들어 :

using std::string;
using std::ostringstream;

여기서 문제는 당신이 할 경우

using namespace std;

std에서 전역 네임 스페이스로 모든 단일 항목을 가져옵니다. 코드에서 실수로 std에서 완전히 알지 못하는 것과 일치하는 이름을 사용할 때 매우 흥미로운 오류 메시지가 나타납니다. 원하는 것을 끌어 들이면 문제가 발생하지 않습니다 (또는 더 정확하게 말하면 코드에서 작업 할 다음 프로그래머에게는 해당 문제가 없습니다).


답변

VJovic에서 알 수 있듯이 using헤더 파일 에는 사용하지 마십시오 . using헤더 파일에서는 소스 파일이 예상하지 못한 방식으로 현재 컴파일 단위 (.cpp 파일)에 영향을줍니다.

using namespace소스 파일에서도 피해야합니다. 이것은 모든 심볼을 소스 파일과 동일한 범위로 가져옵니다. 네임 스페이스에서 특정 기호를 사용하면 사용자가하는 일이 더 명확합니다.


답변

쓰기 using헤더에서하는 모든 종류의 만들 수있는 가장 좋은 방법입니다 불쾌한디버그에 불가능 버그. 마 하지 이렇게.

using namespace XYZ소스 파일에 쓰는 것이 조금 나아지지만 여전히 수많은 두통을 유발할 수 있습니다. 안전한 방법은 사용중인 것을 명시 적으로 지정하는 것 using Foo::Bar입니다.

다음과 같은 Bar.cpp가 있다고 가정 해 봅시다.

//Bar.cpp
using namespace Foo;
namespace
{
    double increment(double v) { return (v + 1); }
}

void Bar::someFunction()
{
    //...
    int currentIndex = 0;
    int nextIndex = increment(currentIndex);
    //...
}

이 기능은 어느 날, 벌금을했다 – 겉으로는 해당 클래스의 코드를 변경하지 않고 – 그 동작이 변경 : 갑자기 currentIndex항상 것 같다 하나 떨어져 . 최근 변경 사항을 살펴보면 코드와 원격으로 관련된 변경 사항도 발견되지 않습니다.

결국 원인을 발견하게됩니다 :
당신은 (간접적으로) Foo.h어딘가에 포함 합니다. Foo 네임 스페이스의 파일에 새로운 기능이 추가되었습니다.

//Foo.h
namespace Foo
{
    //...
    int& increment(int& v) { v += 1; return v; };
    //...
}

어느 것이 increment(int)함수보다 명확하게 더 잘 맞습니다. increment(double)이제 Foo::increment()함수가 Bar::someFunction()대신 호출 됩니다. 으악.

(그리고 포함 트리의 어느 곳에 나 있을 수 using있는 헤더 를 작성한다면 …)using namespace Foo

따라서 … 헤더에 쓰지 말고 소스 파일에 쓰지 않도록using 주의 using namespace하십시오.