2012-01-10 62 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功能,因为我希望代码可以移植到某些较旧的编译器。
  • 具体的编译器错误是“错误C3083:‘C’:在符号左侧的‘::’必须是一种”
+0

**相关:** http://kera.name/articles/2011/02/befriending-your-parser/ – 2012-01-10 00:11:33

回答

3

我敢肯定,编译器认为该空白之间“B”和“:: C”微不足道,所以它试图找到一个成员“C”内“B”

这是正确的。

是否有强烈的理由相对于另一方偏好?我可以期待在其他编译器上正常工作吗?

选项#3对我来说看起来很好(并且是兼容的);也就是说,如果你真的真的坚持这个相当愚蠢的要求。 :)

我自己用它来得出结论a blog post on a very similar "issue"

+0

谢谢。完全限定并不是“安全”的默认要求。在生成的代码中还有一些其他地方需要一些资格来绕过阴影。在任何地方生成完全限定名称比仅仅选择性限定某些事物更容易。如果资格过高导致我有更多问题,我可能会重新考虑,但现在,我认为我仍然满意于权衡。当然,这只适用于生成的代码;我通常不会不必要地限制我手写的代码中的任何内容。 – 2012-01-10 18:14:33

+0

@George:听起来不错。 – 2012-01-10 18:42:28