2011-01-24 14 views
12

我有一個函數簽名C++如何通過非consts的列表,想要consts

void Foo(list<const A*>) 

列表的功能,我想傳遞一個

list<A*> 

我該怎麼做呢? (請注意 - 列表不是恆定的,只有列表中的成員)

+0

你是否嘗試通過列表,因爲它是?如果是這樣,你得到了什麼? – Oswald 2011-01-24 20:49:29

+0

@Oswald,一些可怕的模板鑄造錯誤 – vondip 2011-01-24 20:50:48

+0

錯誤:從'std :: list >'轉換爲非標量類型'std :: list >'requested`? – James 2011-01-24 20:53:22

回答

19

你的問題是,即使T *可以隱式轉換爲T const *,模板系統並不是說「知道」,所以一個whatever<T *>whatever<T const *>完全無關的類型,而且也沒有隱式轉換,從一個到另一個。

爲了避免這個問題,我可能會避免傳遞一個集合。相反,我有這個函數需要一對迭代器。 A list<A *>::iterator可將隱式轉換爲list<A *>::const_iterator。就此而言,我可能會將該函數作爲模板,因此它可以使用任意類型的迭代器。

這可能是爲您節省了不少麻煩 - 一個list是很少容器的一個很好的選擇,所以有一個非常大的機會,有一天你會想改變list<A *>vector<A *>或許deque<A *> - - 如果你使你的函數具有通用性,你就可以在不重寫函數的情況下做到這一點。

-2

我相信你可以通過它,因爲它是。請記住,非const類型可以傳遞給期望const類型的東西,但不是相反的方式!

0

您可以創建一個新列表並使用原始列表中的值填充它。也許並不至於運行時間和內存管理的最有效的解決方案而言,但肯定容易代碼:

list<A*> list1; 
list<const A*> list2; 
for(list<A*>::iterator a=list1.begin(); a!=list1.end(); a++) list2.push_back(*a); 
0

你必須創建列表的副本 - 這是一個傳遞價值論據。有一種非常簡單的方法來創建副本,因爲元素類型具有隱式轉換:所有STL容器都可以從一對迭代器創建。所以,你的情況:

std::list<A*> src; 
Foo(std::list<const A*>(src.begin(), src.end())); 

這是比它需要稍微硬一點,因爲STL表示範圍爲對迭代器和C++的轉換規則對單個對象的工作。