2010-11-26 42 views

回答

1

我猜你已經嘗試過創建像

void doSomething(std::vector<A*>& things) 
{ 
} 

的方法,並試圖做通

std::vector<B*> bList = ...; 
doSomething(bList); 

吧?

爲什麼編譯器會抱怨?因爲這沒有意義。考慮到DoSomething的()嘗試做

things.push_back(new C()); 

這不能作爲「物」的工作實際上是一個std::vector<B*>。但是,如果它是std::vector<A*>,則push_back將起作用。

那麼我們可以從中學到什麼?如果你只從vector中讀取,你所嘗試的只是有意義,然而,vector不是隻讀容器。

一個簡單的包裝顯示一個可能的解決方案(包裝可以根據您的需要進行調整,當然)。但是,我必須指出,使用虛擬方法可能會導致性能處罰。

class A {}; 
class B : public A {}; 

template <class Base> 
class AbstractVectorWrapper 
{ 
public: 
    virtual size_t size() const = 0; 
    virtual Base* getElementAt(int index) const = 0; 
}; 
template <class Base, class Derived> 
class VectorWrapper : public AbstractVectorWrapper<Base> 
{ 
private: 
    std::vector<Derived*> m_vector; 
public: 
    explicit VectorWrapper(std::vector<Derived*> const& vector) 
     : m_vector(vector) 
    { 
    } 
    virtual size_t size() const 
    { 
     return m_vector.size(); 
    } 
    virtual Base* getElementAt(int index) const 
    { 
     return m_vector[index]; 
    } 
}; 

void doSomething(AbstractVectorWrapper<A> const& wrapper) 
{ 
    for (size_t i=0;i<wrapper.size();i++) 
    { 
     A* a = wrapper.getElementAt(i); 
    } 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::vector<A*> as; 
    std::vector<B*> bs; 
    doSomething(VectorWrapper<A,B>(bs)); 
    doSomething(VectorWrapper<A,A>(as)); 


    return 0; 
} 
+0

我知道這是不可能的,因此問題:-) – Gaurav 2010-11-26 04:57:26

1

duck-typing配不上你?考慮以下代碼

template <class T> 
void my_function (std::vector <T*> const &values) { 
    // Use features of A* here 
} 

如果使用指針T不支持功能,這將編譯失敗。通過使用A的功能,我認爲應該保證指向BC的指針也能按預期工作。但是,如果D的界面符合my_function試圖執行的操作,則可以使用向量D *調用此函數。

相關問題