2015-09-27 49 views
2

我需要將std::vector放入std::stack如何用std向量初始化std棧?

這裏是我的方法,到目前爲止,(我建立一個紙牌遊戲):

void CardStack::initializeCardStack(std::vector<Card> & p_cardVector) { 
    m_cardStack = std::stack<Card>(); 
    //code that should initialize m_cardStack with p_cardVector 
} 

注:我不能改變我的方法簽名,因爲它是由老師規定...

待辦事項我必須遍歷整個向量?什麼是最有效的方法來做到這一點? documentation

我試過Jens的答案,但它沒有奏效。

+1

無論是路過常量參考向量,因爲它沒有得到修改,或值和內容移動到堆棧。最後的版本允許編譯器在相同的情況下生成更高效的代碼。 – Jens

+0

'std :: stack <....>'是什麼?默認情況下,'stack'使用'deque',而不是'vector'作爲其底層容器。 –

+0

看我的編輯。我添加了更多上下文。 – AlexB

回答

3

std::stack不具有接受迭代器的構造函數,所以你可以建立一個臨時deque和初始化堆棧與此:

void ClassName::initializeStack(std::vector<AnotherClass> const& v) { 
    m_stackAttribute = std::stack<AnotherClass>(std::stack<AnotherClass>::container_type(v.begin(), v.end())); 
} 

然而,這個副本的每個元素到容器中。爲了獲得最大的效率,你還應該使用移動語義來消除副本

void ClassName::initializeStack(std::vector<AnotherClass>&& v) { 
    std::stack<AnotherClass>::container_type tmp(std::make_move_iterator(v.begin()), std::make_move_iterator(v.end())); 
    m_stackAttribute = std::stack<AnotherClass>(std::move(tmp)); 
} 
+0

此代碼不適用於我。我正在查看文檔,並且發現此方法簽名move-initialize(2)\t 顯式堆棧(container_type && ctnr = container_type()); – AlexB

+0

@AlexB修正了它。堆棧的模板參數丟失。工作代碼在http://cpp.sh/817kk。 – Jens

+0

它編譯但尺寸爲0.堆棧沒有被向量值填充 – AlexB

0

最有效的方法是根本不使用std::stack,只需使用std::vector或更好的用於此使用std::deque

我見過並寫了很多C++代碼(很多),但我還沒有找到的東西stack任何使用(任何有意義使用,即是)。如果底層容器可以在運行時更改或確定其容器類型,則會有所不同,但事實並非如此。

要從std::vector的元素複製到std::deque你可以使用

std::deque<T> stack(vec.begin(), vec.end()); 

這將允許實現用最有效的方式來複制的元素。

要明確回答你的問題:是的,將元素放入堆棧的唯一方法是將它們推入一個循環。這效率不高,但堆棧接口沒有定義其他任何東西。然而,編寫代碼接受std::stack參數的人應該被解僱(除非他/她承諾它永遠不會再發生),並且它的代碼還原爲更明智的東西:您將獲得相同(缺少)「靈活性」,但具有更好的界面。

stack設計的問題是,它的參數化對底層容器類型,而代替(具有任何意義)應該已經參數化的所含元素類型並在構造該類型receving容器(從而隱藏容器類型)。目前的形式基本沒用。

+2

我認爲'std :: stack'和'std :: deque'比直接使用底層容器有一個優勢。他們表達了使用堆棧的意圖,當我看到代碼時,我立即看到堆棧使用了。有了vector,我必須弄清楚它是如何使用的,或者看看現有的有用評論。所以我想說除了其他問題之外,它們還有一個非常有用的含義。 – Jens

+0

@Jens:'std :: deque'是一個容器,而不是一個適配器,它非常有用。另一方面'std :: stack'只是在不提供任何東西的情況下移除方法。提供最少的界面有時很有用,但前提是你可以隱藏/屏蔽真實的提供者;這是接口的工作(但'std :: stack'不是一個接口,因爲底層容器被包含,沒有被引用,並且它的類型必須是已知的編譯時間,消除了接口將添加的任何靈活性)。 – 6502

+0

堆棧和隊列可能不提供功能,但它們表達意圖。閱讀代碼時我覺得這很有用。這也表明在類型級別上的功能合同非常明確。但我同意在STL中有一個概念堆棧或隊列會更好,並且deque應該是一個隊列模型。或者也許是一種表達意圖的類型擦除包裝。我只是不會說這完全沒用。 – Jens