2011-09-07 42 views
2

我有C++中的函數,它需要一個向量並將一些項目推送到它上面。例如:函數多態處理矢量和hash_set

void MyFunction(vector<int>* output); 

我想修改它能夠現在採取矢量一個的hash_set。在Java中,這很容易,只需更改函數以獲取Collection(通用接口)即可。所有MyFunction確實將元素放入它給出的容器中,所以它不應該在意該容器是一個向量還是一個hash_set,只是有一些「插入」元素的概念。

感謝您的幫助!

+3

該函數需要一個指針,而不是一個向量。 –

+2

您可能希望使函數對您的向量進行引用,以便在函數內使用更簡單 - 但這只是一種猜測:)可能指針在給定代碼的情況下更好,但不太可能。 –

回答

3

他會做一個小問題做直線模板。 vector通常使用push_back,而hash_set使用insert。

使用模板,但使用插入函數並插入.end()元素,以便向量保持快速操作 - 它是您的最佳選擇。儘管如果它將插入位置作爲位置提示(它仍然可以工作),你仍然可以放慢你的散列集的速度。

使用insert(iter,val),通過在迭代器位置的元素之前插入新的元素來擴展contianer。這對於序列容器(矢量)是正確的,而關聯容器(hash_set)只是將位置用作提示 - 但插入仍然可以正常工作。假設U與矢量元素類型相同或可以隱式轉換,下面的函數可用於將值U插入任何支持插入的容器(所有STL人員)。

template <typename T, typename U> 
void InsertToContainer(T& container, U val) 
{ 
    container.insert(container.end(), val); 
} 
+3

每個人都支持'insert' ... –

+0

是的:)一些關聯容器將插入位置作爲暗示從哪裏開始尋找排序位置,但是這就是爲什麼我說它可能會減慢地圖,如果你讓它看看首先結束。 –

+0

'x.insert(t,x.end())'應該適用於每個容器,並且效率也很高。對錯誤提示的減速可以忽略不計。 –

1

如果我理解正確的話,你可以用Boost::Variant

+3

你想把一個容器放在一個增強變體中? –

+0

@Tony:OP的功能是指向容器,而不是容器本身。 –

0

函數模板可以讓你以使其更通用的:

template<typename T, typename Cont = std::vector<T> > void MyFunction(T t, Cont c); 

這裏默認的容器是std::vector<T>,但你仍然可以如果你想改變容器。

+0

只有在編譯時知道集合的類型,這纔有效!我認爲在運行時搜索解決方案 – Fox32

+0

是的,但簡單的問題是函數調用方式不同('push_back'與'insert')並且具有不同的簽名。也許插入函數作爲模板參數? –

+2

std :: vector也有插入函數 – Fox32

0

如果需要使用不屬於兩個容器之間常用的方法,您可以創建兩個派生的包裝類具有純虛基類,它定義了你想要的操作與待完成一個共同的接口unordered_setvector不具有類似方法名稱,然後將指針或對基類的引用傳遞給該函數。例如,您的純虛擬基類可以定義用於插入,查找,迭代等的方法,並且可以掩蓋方法名稱的不同以及這兩個容器之間執行這些類型操作。您的派生類型將是基類中純虛方法的實際實現。你的函數需要一個引用或指向基類型的指針,並且由於基類是多態的,你可以調用基類定義的接口方法,並將vectorunordered_set與你的函數一起使用,而不用擔心實現線性容器和關聯容器之間的差異和接口錯誤匹配。