2012-01-24 14 views
10

ここでは、私はG ++ 4.4.6を使用していたテストコード"template"キーワードは不要ですか? [GCC /打ち鳴らす/コモのバグ?]

template <class T> void f() 
{ 
    T t; 
    t.f<T>(0); //compiles even without the "template" keyword, what am I missing? 
} 

class abc 
{ 
    public: 
    template <typename T> 
    void f (int){} 
}; 

int main() 
{ 
    f<abc>(); 
} 

です。ありがとう

P.S:私はかなり私の質問を編集しました。どうか気にしないでください。

EDIT:私はEDGの人にこの質問をしたし、これはマイク・ヘリック我々は--strictモードでエラーと同様に依存可能にする、任意のモードとして、これを診断行う

を言っていたものです名前検索(例えば、--dep_name、--parse_templates)。依存名検索はGNUエミュレーションモードでは無効になっているため、この場合はこのエラーは発生しません。

従属名の処理では、非クラスのプロトタイプインスタンス を有効にする必要があります(下記参照)。非クラスのプロトタイプインスタンシエーションと同様に、 依存名の参照を有効にすると、機能を考慮して記述されていない コードをコンパイルするとコンパイルエラーが発生する可能性があります。

依存名検索ルールでは、依存しない名前を とし、テンプレート定義の使用時点を参照し、その時点で非依存呼び出しで オーバーロード解決を実行する必要があります。 従属呼び出しの場合、考慮される名前のセットは、テンプレート定義の使用時に表示される のセットと、 がインスタンシエーションの時点で引数依存ルックアップによって表示される任意の名前です。 ビルトイン型には名前空間が関連付けられていないので、 ビルトイン型のみの呼び出しは、 テンプレート定義で表示される名前にのみ解決できます。さらに、従属ベースクラスの名前 は、修飾されていないルックアップでは表示されません。

以下は依存名ルックアップを使用する場合 に発生する最も一般的なコードの問題のいくつかを示しています。

template <class T> struct B { 
    void f(); 
    }; 

template <class T> struct A : public B<T> { 
    X x; // error: X not visible yet (formerly an error in strict mode) 
    void g() { 
     f();  // error: B<T>::f not visible 
     this->f(); // must be written this way 
     h(1); // error: h(int) not visible using argument-dependent lookup 
    } 
    }; 
struct X {}; 
void h(int); 
A<int> ai; 
+2

メンバ 'f'の名前をグローバル' f'の名前と共有しないように名前を変更すると、 'template'を指定せずにGCCでコンパイルされません。なぜそれが違いになるのか分かりません。 – interjay

+0

GCCはよりスマートになっています。 :) – iammilind

答えて

8

templateキーワードある必要両方tは依存名で、f<T>ので依存メンバ関数テンプレートの特殊であるため。関連する仕様は14章に散在していますが、14.2/4(C++ 03とC++ 11の両方)から始まります。

問題は間違った名前検索によるものです:GCCは宣言の時点で名前空間スコープ関数テンプレートfを発見され、その後、インスタンス化の時点でabcのメンバ関数テンプレートにfを解決します。

namespace-scope関数テンプレートまたはメンバ関数テンプレートの名前を変更すると、コンパイラから正しい動作が得られます。

これは、長年のgccのバグです:

Code with missing "template" keyword wrongly accepted

Weird clash with same names in different scopes

はまた、これらの両方に対して解決多くの重複バグを参照してください。私はこれのために開いているクラングバグは表示されません。

関数テンプレート内からの名前検索は、C++ 03でunderspecifiedでした。この問題について多くの欠陥が報告されており、詳細とコーナーケースを明確にし、微妙な問題を解決するために、仕様はC++ 11の大きな変更を受けました。

+0

Comeauでもエラーはありません。私はそれが今日標準的なコンパイラであると信じています。 –

+0

お返事ありがとうございます。 –

+0

私はEDGにこのバグを報告します:-) –

2

私は間違っているかもしれないが、私はこれはGCCのバグだと思います。

template <class T> bool f() {T t = {2}; return t.f < 4;} 

struct abc { int f; }; 

int main() { f<abc>(); } 

が、私はそれがうまくコンパイルすることを期待しますが、GCC(およびクラン)はt.f名テンプレート機能、およびクロージング>を期待しているとします。以下のケースを考えてみましょう。標準の関連部分は§14.2/4です。

しかし、私はClangとGCCの両方にこのようなバグが存在する可能性があると主張するのは少し躊躇しています。私はもう少し標準的なダイビングの後に戻ります。

+0

私のコードはComeauでもオンラインでコンパイルされます。 –

+0

ええと、私はこの質問に対する本当の答えに興味があります。私が試したすべてのコンパイラの動作は、私の標準の理解に反しているので、私はたくさんのことを学ぶことができます。 – Mankarse

+1

メンバー 'f'の名前を変更してテンプレート関数の名前を共有しない場合、これはGCC上で正常にコンパイルされます。質問への私のコメントも見てください。 – interjay

関連する問題