2012-01-10 3 views
1
namespace A 
{ 
    class B 
    { 
    public: 
     B(int); 
    }; 
} 

namespace C 
{ 
    class D 
    { 
     static const ::A::B b; 
    }; 
} 

const ::A::B ::C::D::b(0);  // #1 
// const ::A::B C::D::b(0);  // #2 
// const ::A::B (::C::D::b)(0); // #3 

옵션 # 1이 컴파일되지 않습니다. 이제는 잠시 생각해 봤는데 컴파일러가 "B"와 "C"사이의 공백을 중요하지 않으므로 "B"내부에 "C"멤버를 찾으려고합니다. 그게 무슨 일이 일어나고 있다면, 나는 이것들이 두 개의 별개의 정규화 된 이름이라는 것을 컴파일러에게 납득시킬 방법이 필요하다.정규 정적 멤버 정의가 컴파일되지 않습니다.

옵션 # 2와 # 3 모두 매우 최소한의 테스트에서 작동하는 것 같습니다. # 3은 더 자격이 있기 때문에 이름 충돌에 다소 덜 취약한 것처럼 보입니다. # 3은 나에게 다소 전환하기 쉽다. 그래서 # 3쪽으로 기울어 지지만 이상하게 보입니다.

다른 하나를 선호하는 강력한 이유가 있습니까? 두 컴파일러가 다른 컴파일러에서 올바르게 작동 할 것으로 기대할 수 있습니까? 둘 중 하나보다 더 좋은 해결책이 있습니까? 그리고 그 문제에 대해 # 1이 실패하는 이유에 대해 나는 맞습니까?

아마 불필요한 세부 사항

  • 이 질문에 영감 코드는 내가 쓴 소스 코드 생성기에 의해 출력했다. 식별자는 생성기의 입력에서 파생되므로 이름 충돌, 특히 생성기가 감지 할 수없는 범위 사이의 의도하지 않은 섀도 잉에 대해 우려합니다. 그래서 모든 식별자를 가능한 한 완벽하게 한정하기 위해 생성기를 작성했습니다.
  • 저는 VC2010에서 컴파일하고 있습니다.
  • 의도적으로 이 아닌의 C++ 0X 기능을 사용합니다. 코드를 특정 이전 컴파일러로 이식 할 수 있기를 바랍니다.
  • 특정 컴파일러 오류는 " 'C': 오류 C3083의 왼쪽에있는 기호 ':'형식이어야합니다"나는 컴파일러가 공백을 고려 확신
+0

** ** http://kera.name/articles/2011/02/befriending-your-parser/ –

답변

3

"B"와 ":: ​​C"사이의 값이 중요하지 않으므로 "B"안에 멤버 "C"를 찾으려고합니다.

정확하게 맞습니다.

다른 하나를 선호할만한 이유가 있습니까? 두 컴파일러가 다른 컴파일러에서 올바르게 작동 할 것으로 기대할 수 있습니까?

옵션 # 3은 나에게 잘 어울립니다 (준수 함). 즉, 만약 당신이 이라면, 실제로는이 어리석은 요구 사항을 고수해야합니다. :)

나는 이것을 사용하여 결론을 내린다. a blog post on a very similar "issue".

+0

고마워요. 완전한 자격은 "안전한"기본값만큼이나 요구 사항이 아닙니다. 생성 된 코드에는 섀도 잉을 피하기 위해 일부 자격이 필요한 다른 장소가 있습니다. 선택적으로 자격을 부여하는 것보다 어디서나 정규화 된 이름을 생성하는 것이 더 쉬웠습니다. 과도한 자격으로 인해 더 많은 문제가 생기면 다시 생각해 보겠지 만, 지금은 여전히 ​​그 절충안에 만족한다고 생각합니다. 물론 이것은 생성 된 코드에만 해당됩니다. 나는 일반적으로 필자가 손으로 작성한 코드에서 불필요한 자격을 부여하지 않는다. –

+0

@ George : 좋아 보인다. –