2012-10-12 56 views
2

比方說,我有一個基類和派生類,而這需要一個指針的STL向量基類的函數:自動轉換指針列表派生類的指針列表基類

有沒有辦法將指針列表傳遞給派生類?即:

vector<B*> vb; 
// ... add pointers to vb ... 
foo(vb); 

上面將導致以下編譯器錯誤:

error: could not convert ‘vb’ from ‘std::vector<B*>’ to ‘std::vector<A*>’ 

即使B *可轉換爲A *。

最後,如果有普通指針的解決方案,它是否也可以與boost共享指針一起工作?

回答

5

std::vector<B*> and std::vector<A*>在技術上無關。 C++不允許你想要的東西。

一種方法...爲什麼不有一個std::vector<Base*>並插入它Derived對象?這就是多態性,動態調度等重點。

1

你不能傳遞到vector<B*>因爲foo的類型不兼容 - 它不會有所作爲是B*隱式轉換爲A*

你可以做的是建立正確的類型,這是可能的,例如一個新的vector

vector<B*> vb; 
// ... add pointers to vb ... 

vector<A*> va(vb.size()); 
std::transform(vb.begin(), vb.end(), va.begin(), 
       [] (B* p) { return static_cast<A*>(p); }); 
2

您可以從衍生的基礎指針的矢量創建基地指針的臨時矢量:

std::vector<B*> bv; 
foo(std::vector<A*>(bv.begin(), bv.end())); 

但這需要FOO接受你的榜樣const引用不引用等,這是非常低效的,需要的內存分配和複製,

其他,最好的解決辦法是讓你富函數模板:

template <class T> 
void foo(std::vector<T*>& v); 

要確保foo將只爲一個派生,使用type_traits和SFINAE技術中使用,請注意,你叫foo只與第一個參數,第二僅用於消除不從A(SFINAE)派生類型此功能的模板:

#include <type_traits> 

template <class T> 
void foo(std::vector<T*>& av, 
     // don't use this second param 
     typename std::enable_if<std::is_base_of<A,T>::value>::type* = 0) 
2

正如@Science_Fiction前面所說的,它更有意義爲具有保持指針的基本類型的載體和插入指針到基本類型和派生類型,但是如果你不控制crea這些陣列的重刑,您可以使用模板:

template <class T> 
inline void foo(const vector<T*>& v) 
{ 
    for (vector<T*>::const_iterator it = v.begin(); it < v.end(); ++it) 
    { 
     A* a = (A*) *it; 
     cout << a->x << endl; 
    } 
} 
+0

爲了讓事情在我心中更加清晰,這種方法既不屬於'Base'類也不是「Derived'類吧?我的意思是,有模板的關鍵在於具有類型獨立編程。不是嗎? – Recker

相關問題