私はC++ 11標準(よく、n3242ドラフト)とインターネットを精査しましたが、正確な答えは見つかりませんでした。以下のコードは、clang 3.2およびg ++ 4.7.2とVisual Studio 2010で正常にコンパイルされますが、代わりにエラーが発生することが予想されます。 typedefと同じスコープで同じ名前の宣言を使用
#include <iostream>
#include <typeinfo>
typedef int a_t;
namespace a_ns
{
class a_t {};
}
using a_ns::a_t;
int main()
{
a_t a;
std::cout << typeid(a).name() << std::endl;
return 0;
}
はで構築された:
clang -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++
g++ -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++
cl -EHsc -GR a.cpp
打ち鳴らすとg ++ はint型であることを示していると思われる実行ファイルの印刷の "i" を、生成され、typedefが勝ちました。 clは、 "class a_ns :: a_t"という実行可能ファイルを生成しました。これは、Visual Studioが宣言を使用した方が好きだったようです。
次の標準的な抜粋に従ってコードをコンパイルしないと思います。私は、すでに「範囲内の宣言と宣言の競合を使用する」というようなエラーが予想されます。
7.1.3.6 Similarly, in a given scope, a class or enumeration shall not be declared with the same name as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself.
7.3.3.1 A using-declaration introduces a name into the declarative region in which the using-declaration appears.
7.3.3.2 Every using-declaration is a declaration [...]
あり、おそらく何か私は、この動作を説明し、標準で行方不明です(または私は明白なことを見てあまりにも疲れている)のですが、私はそれを見つけるように見えることはできません。
ありがとうございます。
'main()'の本体が空であれば、そのプログラムも無効でしょうか? 7.1.3/6節では、 "*与えられたスコープでは、typedef指定子は、そのスコープで宣言された型の名前を別の型を参照するために**再定義するために使用してはならない* [例:' class complex {/ ... /}; typedef int complex; //エラー:再定義 '-end example *] "*。この問題では、 'typedef'は名前を「再定義」しません。 'using'宣言の後に移動すると、すべてのコンパイラがエラーを出します。 –
@andy mainが空であれば、私たちが見つけた引用によれば、それも無効になるでしょう。他の引用符も適用されるかどうかは関係ありません。通常、クラスA {}に対して名前の再定義が行われます。 typedef AA; '(最初はクラス名だけですが、typedef-nameでもあります)名前は再定義されます。なぜなら、後で名前は1つだけですが、両方の構文属性を持つからです。 Cモデル)。 –
よろしくお願いいたします。 +1 –