我正在寫一個使用類模板的通用容器,並且有一個限制(策略),容器中存儲的項目應該從特定的基類派生。這段代碼爲什麼編譯? (C++模板問題)
這裏是類模板
// GenericContainer.hpp
// --------------------------------------
class ContainerItem
{
protected:
virtual ContainerItem& getInvalid() = 0;
public:
virtual ~ContainerItem();
bool isValid() const;
};
template<typename D, typename B>
class IsDerivedFrom
{
static void Constraints(D* p)
{
B* pb = p; // this line only works if 'D' inherits 'B'
pb = p; // suppress warnings about unused variables
}
protected:
void IsDerivedFrom2() { void(*p)(D*) = Constraints; }
};
// Force it to fail in the case where B is void
template<typename D>
class IsDerivedFrom<D, void>
{
void IsDerivedFrom2() { char* p = (int*)0; /* error */ }
};
template <class T>
class GenericContainer : public IsDerivedFrom<T, ContainerItem>
{
private:
typedef std::vector<T> TypeVect;
void addElement(const T& elem);
TypeVect m_elems;
public:
unsigned int size() const;
T& elementAt(const unsigned int pos);
const T& elementAt(const unsigned int pos) const;
};
template <class T>
void GenericContainer<T>::addElement(const T& elem)
{
m_elems.push_back(elem);
}
template <class T>
unsigned int GenericContainer<T>::size() const
{
return m_elems.size();
}
template <class T>
T& GenericContainer<T>::elementAt(const unsigned int pos)
{
unsigned int maxpos = m_elems.size();
if (pos < maxpos)
return m_elems[pos];
return T::getInvalid();
}
template <class T>
const T& GenericContainer<T>::elementAt(const unsigned int pos) const
{
unsigned int maxpos = m_elems.size();
if (pos < maxpos)
return m_elems[pos];
return T::getInvalid();
}
// Class to be contained (PURPOSELY, does not derive from ContainerItem)
// Data.hpp
//----------------------------------------------------------------
class Data
{ /* implem details */};
// Container for Data items
// Dataset.h
// ----------------------------------------------------------------------------
#include "GenericContainer.hpp"
#include "Data.hpp"
class Dataset: public GenericContainer<Data>
{
public:
Data& getInvalid();
};
// C++ source
// -----------------------------------------------------------
#include "Dataset.hpp"
Dataset ds;
任何人都可以解釋爲什麼上面的代碼編譯的定義?
[編輯]
上面的代碼不應該有兩個原因編譯:
類「數據」不從ContainerItem導出,但它可以被存儲在GenericContainer(如類Dataset所示)。順便說一下,這個問題現在已經解決了,這要歸功於Omifarious和jdv給出的答案
類'Data'不實現在ABC ContainerItem中聲明的純虛方法 - 使用下面答案中推薦的修復,第一個問題(策略執行)已解決,但編譯器未能注意到Data沒有實現ContainerItem'接口'的getInvalid()方法。爲什麼編譯器錯過了這個明顯的錯誤?
順便說一句,編譯器和OS的細節: 克++(Ubuntu的4.4.3-4ubuntu5)4.4.3
如果你解釋爲什麼它不應該在你的意見中編譯,這將有助於我們理解你的問題。 – 2011-01-22 09:36:18
這個問題不應該因爲它太多的代碼讓你閱讀或者你不理解而關閉。這個人犯了一個有趣的錯誤,這個問題值得回答。 – Omnifarious 2011-01-22 09:49:09