2012-01-10 14 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つの別個の修飾名であることを確信させるための何らかの方法が必要です。完全修飾静的メンバー定義はコンパイルされません

オプション#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:いいですね。 –

関連する問題