헤더 내에서 C ++로 중첩 된 네임 스페이스를 표현하는 더 좋은 방법이 있습니까?


98

저는 C ++에서 Java 및 C #으로 전환했고 네임 스페이스 / 패키지 사용이 훨씬 더 낫다고 생각합니다 (잘 구조화 됨). 그런 다음 C ++로 돌아와 동일한 방식으로 네임 스페이스를 사용하려고 시도했지만 필요한 구문이 헤더 파일 내에서 끔찍합니다.

namespace MyCompany
{
    namespace MyModule
    {
        namespace MyModulePart //e.g. Input
        {
            namespace MySubModulePart
            {
                namespace ...
                {
                    public class MyClass    

다음은 나에게도 이상하게 보입니다 (깊은 들여 쓰기를 피하기 위해).

namespace MyCompany
{
namespace MyModule
{
namespace MyModulePart //e.g. Input
{
namespace MySubModulePart
{
namespace ...
{
     public class MyClass
     {

위의 것을 표현하는 더 짧은 방법이 있습니까? 나는 뭔가를 놓치고있다

namespace MyCompany::MyModule::MyModulePart::...
{
   public class MyClass

최신 정보

좋아, 일부는 Java / C # 및 C ++의 사용 개념이 다르다고 말합니다. 정말? 나는 (동적) 클래스 로딩이 네임 스페이스의 유일한 목적이 아니라고 생각합니다 (이것은 매우 기술적 인 관점입니다). 예를 들어 "IntelliSense"와 같이 가독성 및 구조화를 위해 사용하면 안됩니다.

현재 네임 스페이스와 거기에서 찾을 수있는 것 사이에는 논리 / 접착제가 없습니다. Java와 C #은 이보다 훨씬 낫습니다. 왜 <iostream>네임 스페이스를 포함 하고 갖는가 std? 좋습니다. 논리가 포함 할 헤더에 의존해야한다고 말하면 #include가 #include <std::io::stream>또는 같은 "IntelliSense"친숙한 구문을 사용하지 않는 이유는 <std/io/stream>무엇입니까? 기본 라이브러리에서 누락 된 구조화는 Java / C #에 비해 C ++의 약점 중 하나라고 생각합니다.

열렬한 충돌에 대한 고유성이 1 포인트 (C # 및 Java의 포인트이기도 함) 인 경우 프로젝트 이름이나 회사 이름을 네임 스페이스로 사용하는 것이 좋습니다. 그렇게 생각하지 않습니까?

한편으로는 C ++가 가장 유연하다고합니다.하지만 모두가 "이러지 마세요"라고 말했습니까? 나에게 C ++는 많은 일을 할 수 있지만 C #에 비해 많은 경우 가장 쉬운 일에도 끔찍한 구문을 가지고 있습니다.

업데이트 2

대부분의 사용자는 두 수준보다 더 깊은 중첩을 만드는 것이 말도 안된다고 말합니다. 그렇다면 Win8 개발에서 Windows :: UI :: Xaml 및 Windows :: UI :: Xaml :: Controls :: Primitives 네임 스페이스는 어떻습니까? 나는 마이크로 소프트의 네임 스페이스 사용이 합리적이라고 생각하며 실제로 2 단계보다 더 깊다. 더 큰 라이브러리 / 프로젝트에는 더 깊은 중첩이 필요하다고 생각합니다 (ExtraLongClassNameBecauseEveryThingIsInTheSameNameSpace와 같은 클래스 이름을 싫어합니다 ... 그러면 모든 것을 전역 네임 스페이스에 넣을 수도 있습니다.)

업데이트 3-결론

대부분은 "하지 마세요"라고 말하지만 ... 부스트조차도 한두 단계보다 더 깊은 중첩을 가지고 있습니다. 예, 라이브러리이지만 재사용 가능한 코드를 원한다면-자신의 코드를 다른 사람에게 줄 라이브러리처럼 취급하십시오. 또한 네임 스페이스를 사용하여 검색 목적으로 더 깊은 중첩을 사용합니다.


3
namespace키워드 남용 입니까?
Nawaz

4
네임 스페이스와 c # / java 모듈 시스템은 동일한 용도로 사용되지 않으므로 동일한 방식으로 사용해서는 안됩니다. 그리고 더 간단한 구문은 없습니다. 왜냐하면 더 쉽게 할 수 있도록 구문을 제공하는 것은 의미가 없기 때문입니다.
PlasmaHH

@PlasmaHH ... 약점은 C ++의 std lib의 구조화가 누락 된 것입니까? (업데이트에서 내 간단한 예제 참조)
Beachwalker

@Stegi : 왜 그것이 누락되었는지, 그리고 그러한 구조화를 통해 얻을 수있는 확실한 이점에 대해 건전한 주장을 할 수 있다면 잠재적 인 약점에 대해 이야기 할 수 있습니다. 그때까지는 기껏해야 혼란스러운 패키지의 무한 중첩 자바를 호출했습니다.
PlasmaHH

3
@PlasmaHH Intellisense 및 헤더 (패키지) 포함 후 / 후 기타 도우미. 한 회사 내의 대규모 프로젝트는 네임 스페이스가 어떤 "범위"에 포함하는지 명확한 설명을 위해 하나 이상의 중첩 (예 : vw :: golflib :: io)이 필요할 수 있습니다. 글쎄, 당신은 vw ::를 사용할 수 있지만 네임 스페이스가 충돌을 피하기 위해 사용되는 것을 의미했다면, 선언하기가 그렇게 끔찍한 이유는 무엇입니까? 이것은 아무도 그것을 사용하지 않거나 깊이가 1 인 네임 스페이스를 사용하는 지점까지 끝납니다 (종종 제안).
Beachwalker

답변:


132

C ++ 17은 중첩 된 네임 스페이스 정의를 단순화 할 수 있습니다.

namespace A::B::C {
}

다음과 같다

namespace A { namespace B { namespace C {
} } }

cppreference의 네임 스페이스 페이지에서 (8) 참조 :
http://en.cppreference.com/w/cpp/language/namespace


5
... 컴파일러 스위치로 사용 가능/std:c++latest
맑은 달

4
참고 사용하게 될 경우 것으로 /std:c++latest일부 부스트 헤더를 포함하면 비주얼 스튜디오 2015 년 또한 부스트를 사용하여, 당신은 매우 신비 컴파일러 오류가 발생할 수 있습니다. 이 StackOverflow 질문에
Vivit

1
A :: B :: C 네임 스페이스 그대로 작동합니다. 나는 ++ g으로 테스트 한 - 6.0
ervinbosenbacher


17

나는 peterchen의 대답을 전적으로지지 하지만 질문의 다른 부분을 다루는 것을 추가하고 싶습니다.

네임 스페이스 선언은 C ++에서 실제로 #defines 사용을 좋아하는 매우 드문 경우 중 하나입니다 .

#define MY_COMPANY_BEGIN  namespace MyCompany { // begin of the MyCompany namespace
#define MY_COMPANY_END    }                     // end of the MyCompany namespace
#define MY_LIBRARY_BEGIN  namespace MyLibrary { // begin of the MyLibrary namespace
#define MY_LIBRARY_END    }                     // end of the MyLibrary namespace

이렇게하면 네임 스페이스의 닫는 중괄호 근처에 주석이 필요하지 않습니다 (큰 소스 파일의 맨 아래로 스크롤하고 어떤 중괄호가 어떤 범위를 닫는 지에 대한 주석이 누락 된 중괄호를 추가 / 제거 / 균형 조정을 시도한 적이 있습니까?) .).

MY_COMPANY_BEGIN
MY_LIBRARY_BEGIN

class X { };

class Y { };

MY_LIBRARY_END
MY_COMPANY_END

모든 네임 스페이스 선언을 한 줄에 넣으려면 약간의 (매우 추악한) 전 처리기 마법으로도 그렇게 할 수 있습니다.

// helper macros for variadic macro overloading
#define VA_HELPER_EXPAND(_X)                    _X  // workaround for Visual Studio
#define VA_COUNT_HELPER(_1, _2, _3, _4, _5, _6, _Count, ...) _Count
#define VA_COUNT(...)                           VA_HELPER_EXPAND(VA_COUNT_HELPER(__VA_ARGS__, 6, 5, 4, 3, 2, 1))
#define VA_SELECT_CAT(_Name, _Count, ...)       VA_HELPER_EXPAND(_Name##_Count(__VA_ARGS__))
#define VA_SELECT_HELPER(_Name, _Count, ...)    VA_SELECT_CAT(_Name, _Count, __VA_ARGS__)
#define VA_SELECT(_Name, ...)                   VA_SELECT_HELPER(_Name, VA_COUNT(__VA_ARGS__), __VA_ARGS__)

// overloads for NAMESPACE_BEGIN
#define NAMESPACE_BEGIN_HELPER1(_Ns1)             namespace _Ns1 {
#define NAMESPACE_BEGIN_HELPER2(_Ns1, _Ns2)       namespace _Ns1 { NAMESPACE_BEGIN_HELPER1(_Ns2)
#define NAMESPACE_BEGIN_HELPER3(_Ns1, _Ns2, _Ns3) namespace _Ns1 { NAMESPACE_BEGIN_HELPER2(_Ns2, _Ns3)

// overloads for NAMESPACE_END
#define NAMESPACE_END_HELPER1(_Ns1)               }
#define NAMESPACE_END_HELPER2(_Ns1, _Ns2)         } NAMESPACE_END_HELPER1(_Ns2)
#define NAMESPACE_END_HELPER3(_Ns1, _Ns2, _Ns3)   } NAMESPACE_END_HELPER2(_Ns2, _Ns3)

// final macros
#define NAMESPACE_BEGIN(_Namespace, ...)    VA_SELECT(NAMESPACE_BEGIN_HELPER, _Namespace, __VA_ARGS__)
#define NAMESPACE_END(_Namespace, ...)      VA_SELECT(NAMESPACE_END_HELPER,   _Namespace, __VA_ARGS__)

이제 다음과 같이 할 수 있습니다.

NAMESPACE_BEGIN(Foo, Bar, Baz)

class X { };

NAMESPACE_END(Baz, Bar, Foo) // order doesn't matter, NAMESPACE_END(a, b, c) would work equally well

Foo::Bar::Baz::X x;

3 단계보다 깊게 중첩하려면 원하는 개수까지 도우미 매크로를 추가해야합니다.


내가 싫어하는만큼 나는 #define그 전 처리기의 마법에 상당히 감명 받았다. 더 깊은 중첩을 위해 추가적인 헬퍼 매크로를 추가 할 필요가 없을 때만 ... 글쎄, 나는 그것을 어쨌든 사용하지 않을 것이다 .. .
galdin

13

C ++ 네임 스페이스는 구성 요소를 나누거나 정치적 구분을 표현하는 것이 아니라 인터페이스를 그룹화하는 데 사용됩니다.

이 표준은 자바와 유사한 네임 스페이스 사용을 금지하는 방식으로 진행됩니다. 예를 들어 네임 스페이스 별칭 은 깊이 중첩되거나 긴 네임 스페이스 이름을 쉽게 사용할 수있는 방법을 제공합니다.

namespace a {
namespace b {
namespace c {}
}
}

namespace nsc = a::b::c;

그러나 namespace nsc {}네임 스페이스는 original-namespace-name을 사용해서 만 정의 될 수 있기 때문에 오류가됩니다 . 기본적으로 표준은 그러한 라이브러리 의 사용자 에게는 일을 쉽게 하지만 구현 자 에게는 어렵습니다 . 이것은 사람들이 그런 글을 쓰는 것을 막지 만 글을 쓰면 그 효과를 완화시킵니다.

관련 클래스 및 함수 집합에 의해 정의 된 인터페이스 당 하나의 네임 스페이스가 있어야합니다. 내부 또는 선택적 하위 인터페이스는 중첩 된 네임 스페이스에 들어갈 수 있습니다. 그러나 2 개 이상의 수준은 매우 심각한 위험 신호 여야합니다.

::연산자가 필요하지 않은 경우 밑줄 문자와 식별자 접두사를 사용하는 것이 좋습니다.


17
그렇다면 Win8 개발에서 Windows :: UI :: Xaml 및 Windows :: UI :: Xaml :: Controls :: Primitives 네임 스페이스는 어떻습니까? 나는 마이크로 소프트의 네임 스페이스 사용이 합리적이라고 생각하며 실제로 2 단계보다 더 깊다.
Beachwalker

2
2 개 미만의 레벨을 사용하는 것은 위험 신호이며 3 또는 4를 사용하는 것은 완벽합니다. 말이되지 않을 때 플랫 네임 스페이스 계층 구조를 얻으려고하면 네임 스페이스의 목적 자체가 실패하여 이름 충돌을 피할 수 있습니다. 나는 당신이 인터페이스에 대해 하나의 수준을 가지고 있고 하위 인터페이스와 내부에 대해 다른 수준을 가져야한다는 데 동의합니다. 그러나 그 주변에는 회사 네임 스페이스 (중소 기업의 경우)에 대해 적어도 하나 이상의 수준이 필요하거나 회사 및 부서 (대기업의 경우)에 대해 두 개가 필요합니다. 그렇지 않으면 동일한 이름을 가진 다른 인터페이스에서 사람과 충돌됩니다 인터페이스 네임 스페이스는 다른 곳에서 개발
Kaiserludi

@Kaiserludi company::divisionover 의 기술적 이점은 무엇입니까 company_division?
Potatoswatter

@Potatoswatter Inside company :: anotherDivsion 당신은 더 짧은 'division'을 사용할 수 있습니다. 'using namespace'를 사용하여 더 높은 수준의 네임 스페이스를 오염시키지 않아야하는 헤더 내에서도 company :: division을 참조하십시오. 회사 네임 스페이스 외부에서 여전히 '사용 네임 스페이스 회사'를 수행 할 수 있습니다. 부서 이름이 범위의 다른 네임 스페이스와 충돌하지 않지만 일부 부서 네임 스페이스 내부의 인터페이스 이름이 충돌하여 'use namespace company_division;'을 수행 할 수없는 경우.
Kaiserludi

3
@Potatoswatter 요점은 실제로 무료로 얻을 수 있으며 (company :: division은 company_division보다 길지 않음) 사용하기 위해 먼저 추가 네임 스페이스 별칭을 정의 할 필요가 없다는 것입니다.
Kaiserludi

7

아뇨, 그러지 마세요.

네임 스페이스의 목적은 주로 전역 네임 스페이스의 충돌을 해결하는 것입니다.

두 번째 목적은 기호의 지역 약어입니다. 예를 들어 복잡한 UpdateUI방법은를 사용하여 using namespace WndUI더 짧은 기호를 사용할 수 있습니다 .

저는 1.3MLoc 프로젝트에 있으며 우리가 가진 유일한 네임 스페이스는 다음과 같습니다.

  • 가져온 외부 COM 라이브러리 (주로 #import및 간의 헤더 충돌을 격리하기 위해 #include windows.h)
  • 특정 측면 (UI, DB 액세스 등)에 대한 한 수준의 "공용 API"네임 스페이스
  • 공용 API의 일부가 아닌 "구현 세부 정보"네임 스페이스 (.cpp의 익명 네임 스페이스 또는 ModuleDetailHereBeTygers헤더 전용 라이브러리의 네임 스페이스)
  • 열거 형은 내 경험에서 가장 큰 문제입니다. 그들은 미친 듯이 오염시킵니다.
  • 나는 아직도 그것이 완전히 너무 많은 네임 스페이스라고 느낀다.

이 프로젝트에서 클래스 이름 등은 2 자 또는 3 자 "지역"코드 (예 : CDBNode대신 DB::CNode)를 사용합니다. 후자를 선호하는 경우 두 번째 수준의 "공용"네임 스페이스를위한 공간이 있지만 더 이상은 없습니다.

클래스 별 열거 형 등은 해당 클래스의 구성원이 될 수 있습니다 (항상 좋은 것은 아니라는 데 동의하며 때로는 그래야하는지 여부를 말하기가 어렵습니다).

바이너리로 배포되고 자체 네임 스페이스를 제공하지 않고 쉽게 하나에 넣을 수없는 타사 라이브러리에 큰 문제가있는 경우를 제외하고는 "회사"네임 스페이스가 거의 필요하지 않습니다 (예 : 바이너리 분포). 그래도 내 경험상 그것들 을 네임 스페이스로 강제 하는 것은 훨씬 쉽습니다.


[편집] Stegi의 후속 질문으로 당 :

그렇다면 Win8 개발에서 Windows :: UI :: Xaml 및 Windows :: UI :: Xaml :: Controls :: Primitives 네임 스페이스는 어떻습니까? Microsoft의 네임 스페이스 사용이 합리적이라고 생각하며 실제로 2 단계보다 더 깊습니다.

충분히 명확하지 않은 경우 죄송합니다. 두 수준은 엄격한 제한이 아니며 더 많은 수준은 본질적으로 나쁘지 않습니다. 제 경험상, 대규모 코드 기반에서도 두 개 이상은 거의 필요 하지 않다는 점을 지적하고 싶었습니다 . 더 깊거나 더 얕은 중첩은 트레이드 오프입니다.

이제 Microsoft 사례는 틀림없이 다릅니다. 아마도 훨씬 더 큰 팀이며 모든 코드는 라이브러리입니다.

Microsoft가 여기에서 네임 스페이스 가 광범위한 라이브러리 의 검색 가능성 에 기여하는 .NET 라이브러리의 성공을 모방하고 있다고 가정 합니다. (.NET에는 약 18000 개의 유형이 있습니다.)

또한 네임 스페이스에 최적 (크기 순서) 기호가 있다고 가정합니다. 1은 말이 안 돼요, 100은 맞아요, 10000은 분명히 많이 요.


TL; DR : 이것은 트레이드 오프이며, 우리는 정확한 숫자가 없습니다. 안전하게 플레이하고 어떤 방향으로도 무리하지 마십시오. "그렇게하지 마라"는 "당신은 그것에 문제가 있고, 나는 그것에 문제가있을 것이고, 당신이 그것을 필요로하는 이유를 알지 못합니다."에서 온 것입니다.


8
그렇다면 Win8 개발에서 Windows :: UI :: Xaml 및 Windows :: UI :: Xaml :: Controls :: Primitives 네임 스페이스는 어떻습니까? 나는 마이크로 소프트의 네임 스페이스 사용이 합리적이라고 생각하며 실제로 2 레벨보다 더 깊다.
Beachwalker 2012-07-26

2
전역 액세스 상수가 필요한 경우 Constants이름이. 필요한 경우 이름 충돌을 방지하기 위해 추가 네임 스페이스를 사용합니다. 이 Constants네임 스페이스는 자체적으로 프로그램의 시스템 코드에 대한 포괄 네임 스페이스에 포함되며 SysData. 이 세 가지 또는 네 개의 네임 스페이스를 포함하는 완전한 이름을 (예 : 생성 SysData::Constants::ErrorMessages, SysData::Constants::Ailments::Bitflags또는 SysData::Defaults::Engine::TextSystem).
저스틴 시간 - 분석 재개 모니카

1
실제 코드에서 상수가 필요한 경우,이를 필요로하는 모든 함수 using는 적절한 이름을 가져 오는 지시문을 사용하여 이름 충돌 가능성을 최소화합니다. 가독성이 향상되고 주어진 코드 블록의 종속성을 문서화하는 데 도움이됩니다. 상수와는 별개로 가능한 경우 두 개의 네임 스페이스 (예 :SysData::ExceptionsSysData::Classes)에 합니다.
저스틴 시간 - 분석 재개 모니카

2
전체적으로는 일반적으로 최소한의 중첩 된 네임 스페이스를 사용하는 것이 가장 좋지만, 어떤 이유로 (상수 또는 변경 가능, 바람직하게는 전자) 전역 개체가 필요한 경우 여러 중첩 네임 스페이스를 사용해야합니다. 사용을 문서화하고 잠재적 인 이름 충돌을 최소화하기 위해 적절한 범주로 구분합니다.
저스틴 시간 - 분석 재개 모니카

2
-1 : 객관적인 이유 없이 "이 작업을 수행하지 마십시오." (나중에 설명이 있음에도 불구하고). 언어는 중첩 된 네임 스페이스를 지원하며 프로젝트는이를 사용하는 데 좋은 이유가있을 수 있습니다. 그러한 이유와 그에 대한 구체적이고 객관적인 단점에 대한 논의는 내 반대표를 뒤집을 것입니다.
TypeIA 2017

5

다음은 Lzz (Lazy C ++) 문서 의 인용문입니다 .

Lzz는 다음 C ++ 구문을 인식합니다.

네임 스페이스 정의

이름이 지정되지 않은 네임 스페이스와 포함 된 모든 선언이 소스 파일에 출력됩니다. 이 규칙은 다른 모든 규칙을 재정의합니다.

명명 된 네임 스페이스의 이름을 정규화 할 수 있습니다.

   namespace A::B { typedef int I; }

다음과 같습니다.

   namespace A { namespace B { typedef int I; } }

물론 이러한 도구에 의존하는 소스의 품질은 논란의 여지가 있습니다. C ++에 의해 유발 된 구문 질환이 다양한 형태를 취할 수 있다는 것을 보여주는 호기심이 더 많습니다 (저도 저도 있습니다 ...)


2

두 표준 (C ++ 2003 및 C ++ 11)은 네임 스페이스의 이름이 식별자라는 매우 명시 적입니다. 이는 명시 적 중첩 헤더가 필요함을 의미합니다.

네임 스페이스의 단순한 이름 외에 정규화 된 식별자를 배치하는 것은 큰 문제가 아니라는 느낌이 들지만 어떤 이유로 든 허용되지 않습니다.


2

이 문서는 주제를 다소 잘 다루고 있습니다. Namespace Paper

이것은 기본적으로 요약됩니다. 네임 스페이스가 길수록 사람들이 using namespace지시문 을 사용할 가능성이 높아집니다 .

따라서 다음 코드를 보면 이것이 당신을 해칠 예를 볼 수 있습니다.

namespace abc { namespace testing {
    class myClass {};
}}

namespace def { namespace testing {
    class defClass { };
}}

using namespace abc;
//using namespace def;

int main(int, char**) {
    testing::myClass classInit{};
}

이 코드는 잘 컴파일되지만 줄의 주석 처리를 제거 //using namespace def;하면 "testing"네임 스페이스가 모호 해지고 명명 충돌이 발생합니다. 즉, 타사 라이브러리를 포함하여 코드 기반이 안정된 상태에서 불안정한 상태로 이동할 수 있습니다.

C #을에서 사용할하더라도 using abc;using def;컴파일러는 그것을 인식 할 수 있습니다 testing::myClass, 심지어는 myClass단지에 abc::testing네임 스페이스,하지만 C ++에서이 문제를 인식하지 못합니다 그것은 충돌로 감지된다.


0

예, 다음과 같이해야합니다.

namespace A{ 
namespace B{
namespace C{} 
} 
}

그러나 사용되지 않아야하는 방식으로 네임 스페이스를 사용하려고합니다. 질문을 확인 하면 유용 할 것입니다.


0

다음 구문을 사용할 수 있습니다.

namespace MyCompany {
  namespace MyModule {
    namespace MyModulePart //e.g. Input {
      namespace MySubModulePart {
        namespace ... {
          class MyClass;
        }
      }
    }
  }
}

// Here is where the magic happens
class MyCompany::MyModule::MyModulePart::MySubModulePart::MyYouGetTheIdeaModule::MyClass {
    ...
};

이 구문은 C ++ 98에서도 유효하며 중첩 된 네임 스페이스 정의가 있는 C ++ 17에서 현재 사용 가능한 구문과 거의 유사합니다. .

즐거운 중첩 해제!

출처 :


그것은 더 나은 솔루션이 대신 검색되는 질문에서 언급 된 구문입니다. 이제 C ++ 17은 수락 된 답변에 명시된대로 유효한 대안입니다. 죄송합니다. 질문과 답변을 읽지 않은 것에 대해 반대 투표하십시오.
Beachwalker

@Beachwalker 문법에 얽매이지 말자. 위의 네임 스페이스 선언은 허용 된 답변과 동일 할 수도 있습니다. 이 답변으로 강조하고 싶은 요점은 OP가 그가 놓친 것이라고 말한 것과 네임 스페이스 혼란 아래에서 내가 한 일입니다. 내가 볼 수있는 한 모든 사람들이 네임 스페이스 내의 모든 것을 선언하는 데 초점을 맞춘 것처럼 보이지만 내 대답은 중첩 된 혼란에서 벗어나고 OP 가이 구문을 4 년 전에 언급 한 사람 이이 질문에 대해 감사했을 것이라고 확신합니다. 처음으로 물었다.
smac89

-1

[편집 :]
c ++ 17 중첩 네임 스페이스가 표준 언어 기능으로 지원되기 때문에 ( https://en.wikipedia.org/wiki/C%2B%2B17 ). 현재이 기능은 g ++ 8에서 지원되지 않지만 clang ++ 6.0 컴파일러에서 찾을 수 있습니다.


[결론 :] 기본 컴파일 명령으로
사용 clang++6.0 -std=c++17합니다. 그러면 모든 것이 잘 작동하고 namespace OuterNS::InnerNS1::InnerNS2 { ... }파일에서 컴파일 할 수 있습니다.


[ORIGINAL ANSWER :]
이 질문은 약간 오래되었으므로 계속 진행했다고 가정하겠습니다. 그러나 여전히 답을 찾고있는 다른 사람들을 위해 다음 아이디어를 생각해 냈습니다.

메인 파일, 네임 스페이스 파일, 컴파일 명령 / 결과 및 명령 줄 실행을 보여주는 Emacs 버퍼.

(여기 Emacs에 대한 광고를 만들어도 될까요?)?) 이미지를 게시하는 것은 단순히 코드를 게시하는 것보다 훨씬 쉽고 읽기 쉽습니다. 나는 모든 코너 케이스에 대한 완전한 답변을 제공 할 의도는 없으며, 단순히 영감을주기위한 것입니다. (저는 C #을 전적으로 지원하며, C #은 주로 사용 편의성 때문에 인기가 많기 때문에 C ++는 일부 OOP 기능을 채택해야한다고 생각합니다.)


업데이트 : C ++ 17에는 중첩 네임 스페이스 ( nuonsoft.com/blog/2017/08/01/c17-nested-namespaces )가 있으므로 이전 버전의 C ++를 사용하지 않는 한 내 대답이 더 이상 관련이없는 것처럼 보입니다. .
ワイきんぐ

1
내가 Emacs를 좋아하는만큼 이미지를 게시하는 것은 이상적이지 않습니다. 텍스트 검색 / 인덱싱을 피하고 시각 장애가있는 방문자가 답변에 접근하기 어렵게 만듭니다.
하인리히 모니카 지원
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.