4

次のC++コードが期待どおりに動作しない理由を誰かが説明できますか?

struct Object {   
  template< int i >
  void foo(){ } 
};

template<int counter>
struct Container {
  Object v[counter];

  void test(){
    // this works as expected
    Object a; a.foo<1>();

    // This works as well:
    Object *b = new Object(); b->foo<1>();

    // now try the same thing with the array:  
    v[0] = Object(); // that's fine (just testing access to the array)

# if defined BUG1
    v[0].foo<1>();   // compilation fails 
# elif defined BUG2
    (v[0]).foo<1>(); // compilation fails
# elif defined BUG3
    auto &o = v[0];
    o.foo<1>();      // compilation fails
# else
    Object &o = v[0];
    o.foo<1>();      // works
# endif
  }
};

int main(){
  Container<10> container;
}

上記のコードは、フラグなしで正常にコンパイルされます。フラグBUG1からBUG3のいずれかが設定されている場合、GCC4.6または4.7とclang3.2のいずれかでコンパイルが失敗します(これは、GCCのバグではないことを示しているようです)。

21行目から29行目は、意味的にまったく同じことを行っています(つまり、Object配列の最初の要素のメソッドを呼び出しています)が、最後のバージョンのみがコンパイルされます。この問題は、テンプレートオブジェクトからテンプレート化されたメソッドを呼び出そうとした場合にのみ発生するようです。

BUG1は、呼び出しを記述するための単なる「通常の」方法です。

BUG2も同じですが、優先順位の問題が発生した場合に備えて、配列アクセスは括弧で保護されています(ただし、そうすべきではありません)。

BUG3は、型推論も機能していないことを示しています(c ++ 11サポートでコンパイルする必要があります)。

最後のバージョンは正常に機能しますが、一時変数を使用して参照を格納することで問題が解決する理由がわかりません。

他の3つが無効である理由を知りたいです。

ありがとう

4

2 に答える 2

1

次のように使用する必要がありますtemplate

v[0].template foo<1>();  

auto &o = v[0];
o.template foo<1>();     

の宣言はvテンプレート引数に依存しているためv、依存名になります。

ここで、templateキーワードはコンパイラーに、後に続くものはすべてテンプレート(あなたの場合fooは実際にテンプレート)であることを伝えます。fooがテンプレートでない場合、templateキーワードは必要ありません(実際、エラーになります)。

問題はo.foo<1>()、2つの方法で解析/解釈できることです。1つは期待どおり(関数呼び出し)であり、もう1つは次のとおりです。

(o.foo) < 1  //partially parsed

つまり、 fooはメンバーデータ(関数ではない)であり、それを。と比較しました1。したがって、との<比較o.fooに使用されないコンパイラに1、テンプレート引数を関数テンプレートに渡すために使用されることを伝えるには、キーワード1を使用する必要があります。template

于 2012-12-01T15:55:41.037 に答える
1

テンプレート内では、式はタイプ依存または依存にすることができます。14.6.2から:

タイプと式は、テンプレートパラメータのタイプや値に依存する場合があります

あなたの場合、counterはテンプレート引数であり、の宣言はvそれに依存しv[0]値に依存する式を作成します。したがって、名前fooは従属名であり、次のように言ってテンプレート名として明確にする必要があります。

v[0].template foo<1>();
于 2012-12-01T16:00:47.953 に答える