実際、 C++ ドラフトの標準セクションの 3.3.10
名前の非表示の段落2を見ると、変数を使用してクラスの名前を非表示にすることは有効です(強調鉱山):
クラス名 (9.1) または列挙名 (7.2) は、同じスコープで宣言された変数、データ メンバー、関数、または列挙子の名前によって非表示にすることができます。クラスまたは列挙名と、変数、データ メンバー、関数、または列挙子が同じスコープで (任意の順序で) 同じ名前で宣言されている場合、クラスまたは列挙名は、変数、データ メンバー、関数、または列挙子名が表示されます。
それは良い習慣ではないと思いますし、コードの保守が難しくなるでしょう。このコード行は、実際には関数を宣言しています。
a a1();
代わりに、この pre -C++11を使用することもできます:
a a1 ;
またはC++11で導入された一様な初期化:
a a1{} ;
名前の非表示に戻るとclang
、設定されている警告レベルに関係なく、このコードでこれについて警告することに驚きました。
int main()
{
a a;
a a2 ;
}
次のメッセージが表示されます。
main.cpp:12:10: note: class 'a' is hidden by a non-type declaration of 'a' here
a a;
^
から同様の警告を取得することはできませんがgcc
。
アップデート
以前に統一初期化の疣贅について行ったこのコメントについて考えてみると、それa1
がどういうわけか正しいタイプではないのではないかと疑っていた場合、 typeidを使用して何が起こっているのかをデバッグできたことに気付きました。たとえば、このコード:
std::cout << typeid(a).name() << std::endl ;
std::cout << typeid(a1).name() << std::endl ;
Coliru live exampleで次の出力が得られます。
1a
F1avE
これをc++filtに渡すと、次の出力が得られます。
a () // A function that returns type a
a // type a