我(隱約地)知道模板沒有實例化,如果它是而不是使用。例如,即使T::type
在T = int
時沒有意義,以下代碼也可以很好地編譯。虛擬對類模板成員使用的影響
template<typename T>
struct A
{
void f() { using type = typename T::type; }
};
A<int> a; //ok
它編譯因爲f()
不是使用,所以它不會被實例化—這樣的T::type
有效性仍然選中。不要緊,如果其他一些成員函數g()
調用f()
。
template<typename T>
struct A
{
void f() { using type = typename T::type; }
void g() { f(); } //Is f() still unused?
};
A<int> a; //ok
這也是compile fines。但在這裏,我意識到我對「使用」的定義的理解含糊不清。我問:
- 是
f()
還未使用?究竟如何?
我可以清楚地看到它被用在g()
裏面。但後來我認爲g()
沒有使用,f()
也沒有使用,從實例化的角度來看。這似乎夠合理。至今。
但是如果我添加virtual
關鍵字g()
,它不會編譯:
template<typename T>
struct A
{
void f() { using type = typename T::type; }
virtual void g() { f(); } //Now f() is used? How exactly?
};
A<int> a; //error
它導致compilation error因爲現在它嘗試實例f()
。我不明白這種行爲。
有人能解釋一下嗎?特別是virtual
關鍵字對類模板成員的「使用」定義的影響。
如果我沒有記錯,'virtual'強制實例化成員函數,因爲現在幾乎不可能靜態評估是否使用該函數。在實踐中,你要求創建一個充滿指向函數指針的v表......所以函數需要存在,所以我們可以給它一個指針。 –
結構模板只有在使用時纔會被實例化。它可能是整個結構或沒有。它與g或f沒有任何關係。 – Sarien
@Sarien:它的確如此,模板類的成員函數只有在使用ODR的時候纔會被實例化。 –