假設我有一個模板類這樣:虛函數和泛型編程
template <class T>
class Foo
{
public:
explicit Foo(const T& value)
: m_Value(value)
{
}
bool Bar(const T& value)
{
return m_Value == value;
}
private:
T m_Value;
};
而且,我們說,我有一些其他的用戶類型,如:
class A
{
};
那麼這個代碼是完全有效的,即使類一個沒有定義相等操作符:
int main(int argc, char* argv[])
{
A a;
Foo<A> foo(a);
return 0;
}
但是,如果我做美孚::酒吧()虛:
virtual bool Bar(const T& value)
{
return m_Value == value;
}
代碼不再編譯:
錯誤C2676:二進制 '==': 'A' 不定義此運算符或轉換爲預定義運營商可接受的類型
我完全理解爲什麼這是一個問題。糾正我,如果我錯了,但我的理解是,因爲該函數是虛擬的,編譯器必須編譯該函數(即使它從來沒有被調用),以便它可以在Foo的v表中引用它。
我想知道是否有解決此問題的方法。我想要一個模板類來處理只能實現部分接口的泛型類型。只要沒有使用缺失的位,代碼應該編譯得很好。這與很多STD容器已經工作的方式類似,但它們不使用虛擬功能。
我該怎麼做?有沒有一個優雅的解決方案呢?
如果一個函數是虛擬的,它必須被定義和編譯。這是根本。 –
類模板的非虛擬成員函數本身是函數模板,僅在第一次使用時才實例化。相比之下,虛擬成員函數總是作爲類模板特化實例的一部分而被實例化。 –
當一個類模板被實例化時,其成員函數的*聲明*被編譯,而不是它們的主體。而虛擬非純成員函數總是被odr使用,因此完全編譯爲類模板實例化的一部分。 – 0x499602D2