![](/img/trans.png)
[英]Accessing a method of a class object stored in a vector using an Iterator. How?
[英]C++ - Using array/pointers in vector (or other container) constructor that expects type Iterator. How is that possible?
下面的文字來自C ++在線課程。 它說vector
類的構造函數
template <class InputIterator>
vector ( InputIterator first, InputIterator last, const Allocator& = Allocator() );
可以接收指針作為第一個( InputIterator first
)和第二個參數( InputIterator last
)。
下一個構造函數使用迭代器進行初始化。 它將創建一個向量,該向量具有從第一個(包含)到最后一個(不含)的值的副本。 在最典型的情況下,此構造函數使用現有集合中的元素創建新的向量。 但是由於將迭代器定義為一組操作而不是某種類型的事實,因此也可以使用普通指針。 此評論得出一個結論,您可以使用普通的C ++數組初始化集合。 實際上,您可以。
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int a1[]={1,2,3,4,5,6,7,8,9,10};
//first one
vector<int> v1(a1, a1+10);
cout<<"Size (v1): "<<v1.size()<<endl;
for(unsigned i = 0; i < v1.size(); ++i)
{
cout<< v1[i]<<" ";
}
cout<<endl;
//second one;
vector<int> v2(a1+5,a1+10);
cout<<"Size (v2): "<<v2.size()<<endl;
for(unsigned i = 0; i < v2.size(); ++i)
{
cout<< v2[i]<<" ";
}
cout<<endl;
return 0;
}
我可以習慣這一點,但是我真的不明白為什么有這種可能。 我想了解這項技術。
在這種情況下(請參見代碼),我的問題是,我怎么可能只簡單地放置一個數組地址而不是一個迭代器?
在上面的代碼中,將一個int *
類型的元素作為InputIterator
類型的參數。 這使我感到困惑。
所有的故事都是關於構造對迭代器的期望。 它期望能夠增加它(使用++),以尊重它(使用*)。 插入器既可以是重載++和*運算符的類,也可以是自然支持這兩種操作的基本指針類型。
實際上,C ++迭代器經過了精心設計,以概括指針的語義並模仿其語法(因此, operator*
重載)。
請參閱原始SGI文檔中的一般性討論或此處的最新C ++版本的處理,並特別注意:
std::vector
構造函數僅需要InputIterator 如果您真的不相信#1,那么您可能還希望看到標准庫顯式地為原始指針提供迭代器特征 ,並且如果您仍在苦苦掙扎,請看一下構造函數的實現,以及請放心,針對其參數的所有操作格式都正確。
要回答最后一個問題,指針指向內存中的位置。 由於存儲器是隨機訪問的,因此指針可以歸類為具有隨機訪問的指針。 迭代器具有相同的分類類型。 cplusplus.com的布局很好,可以顯示此處支持哪種類型的迭代器。 這樣,我們可以看到輸入迭代器是最低的類型,並且它們可以執行最少的操作。 由於指針與隨機訪問迭代器相同,並且隨機訪問迭代器可以執行輸入迭代器可以執行的所有操作,因此沒有任何問題。
如果這是相反的方法,並且您有一個需要隨機訪問迭代器的函數,並且提供了前向迭代器,則不能保證代碼會正常工作。 這是因為該函數可能依賴於某個操作,而隨機訪問迭代器可以執行此操作,而正向迭代器則無法執行。
通常,當您編寫這種類型的代碼並指定所需的迭代器類型時,可以指定允許代碼編譯的最小類型。 只是打印內容的東西只需要一個正向迭代器,因為您只是遍歷需要隨機訪問的內容時。
因為數組將其元素存儲在連續內存中。 因此,如果您知道類型的大小以及第一個元素的指針,則可以找出所有其余元素的地址。
int values[10];
&values[5] == &values[0] + 5 // due to pointer arithmetic
§5.7加法運算符
加法運算符+和-從左到右分組。 通常對算術或枚舉類型的操作數執行算術轉換。
另外 ,兩個操作數都應具有算術或無作用域枚舉類型,或者一個操作數應是指向完全定義的對象類型的指針 , 另一個操作數應具有整數或無作用域的枚舉類型 。
對於減法,應滿足下列條件之一:
—兩個操作數都具有算術或非范圍枚舉類型; 要么
—兩個操作數都是相同完全定義對象類型的cv限定或cv非限定版本的指針; 要么
—左操作數是指向完全定義的對象類型的指針,而右操作數具有整數或無作用域的枚舉類型。...
當將具有整數類型的表達式添加到指針或從指針中減去時,結果將具有指針操作數的類型。 如果指針操作數指向數組對象的元素,並且數組足夠大,則結果指向與原始元素偏移的元素,以使結果數組元素和原始數組元素的下標之差等於整數表達式 。 換句話說,如果表達式P指向數組對象的第i個元素,則表達式(P)+ N(相當於N +(P))和(P)-N(其中N的值為n)表示分別存在於數組對象的第i + n個元素和第i-n個元素中,前提是它們存在。 此外,如果表達式P指向數組對象的最后一個元素,則表達式(P)+1指向數組對象的最后一個元素之后,如果表達式Q指向數組對象的最后一個元素之后,表達式(Q)-1指向數組對象的最后一個元素。 如果指針操作數和結果都指向同一數組對象的元素,或者指向數組對象的最后一個元素,則求值不會產生溢出; 否則,行為是不確定的。
因此,基本上,該標准定義了指針T*
和整數類型之間的算術
T* t + n // where n is an offset (of integral type)
從初始t
得出另一個n * sizeof(T)
T*
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.