有人能解釋一個模板方法時,爲什麼下面的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之一被設置,則編譯失敗,GCC 4.6或4.7以及3.2版(這似乎表明它不是GCC錯誤)。
21到29行在語義上完成同樣的事情(即調用Object數組的第一個元素的方法),但只有最後一個版本編譯。這個問題似乎只在我嘗試從模板對象調用模板化方法時出現。
BUG1只是編寫調用的「正常」方式。
BUG2是同樣的事情,但是如果存在優先級問題(但不應該有),則數組訪問受括號保護。
BUG3顯示類型推斷不工作(需要用C++ 11支持編譯)。
上一個版本可以正常工作,但我不明白爲什麼使用臨時變量來存儲引用可以解決問題。
我很想知道爲什麼其他三個是無效的。
感謝
嘗試'v [0] .template富<1>();'。 –
@KerrekSB:有趣的是爲什麼這是必要的。看起來v [0]不是依賴表達式,因此編譯器應該能夠在解析模板時解析其類型。 –
@VaughnCato:我還沒有測試過,我也不確定。這只是一個建議......畢竟,OP並沒有告訴我們錯誤是什麼,只有這麼多的猜測才能做到。 –