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の左にある記号 『::』タイプでなければなりません」私は、コンパイラは空白を考慮かなり確信している
**関連:** http://kera.name/articles/2011/02/befriending-your-parser/ –