次の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つが無効である理由を知りたいです。
ありがとう