簡體   English   中英

將向量迭代器轉換為指針

[英]Convert vector iterator to pointer

有沒有辦法將vector::iterator轉換為指針而無法訪問向量本身? 這僅在vector可用時才有效:

typedef vector<int> V;
int* to_pointer1( V& v, V::iterator t )
{
    return v.data() + (t-v.begin() );
}

但是,如果沒有vector ,怎么能這樣做呢? 這不起作用:

int* to_pointer2( V::iterator t )
{
    // the obvious approach doesn't work for the end iterator
    return &*t;
}

事實上,我本來希望這是一個非常基本和流行的問題,但由於某種原因,我找不到它。

一般來說,你不能保證對應於指的是普通的載體項目迭代器的指針。

特別是std::vector<bool>是專用的,因此&*it甚至不會編譯。

然而,對於其他向量,它只有1個正式迂腐,阻止你做&*it也為最終迭代器。 在C99中,正如我記得的那樣,當p是結束指針時,正式有效做&*p ,並且std::vector的目標是支持所有普通的原始數組符號。 如果我需要這個,我會忽略正式迂腐,並編寫代碼,以期對標准的未來修訂將消除那個想象的障礙。

所以,在實踐中,只需做&*it :)

#include <iostream>
#include <vector>
using namespace std;

auto main() -> int
{
    vector<int> x( 5 );
    cout << &*x.begin() << " " << &*x.end() << endl;
    cout << &*x.end() - &*x.begin() << endl;        // Works nicely IN PRACTICE.
}

但請記住,你不能為vector<bool>做這個。


1)在評論別處用戶十五邊形的言論:“嘗試-D_GLIBCXX_DEBUG ,如下記載: gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html 。” G ++經常提供攜帶任何正式的UB到前面的一些手段,例如正式UB循環的“優化”。 在這種特殊情況下的解決方案只是不要求它這樣做,但更一般地,人們可能必須明確地要求它不這樣做。

不,這目前不可行。 n3884 連續迭代器:隨機訪問的改進迭代器提出了一個自由函數std::pointer_from ,它可以滿足你的要求:

表達式: std::pointer_from(a)
返回類型: reference
操作語義:如果a是可解除引用的,則std::address_of(*a) ; 否則,如果a可從可解除引用的迭代器b到達,則std::pointer_from(b) + (a – b) ; 否則是有效的指針值([basic.compound])。

對於最終迭代器,你所要求的是不可能的; 根據定義,結束迭代器指向超出數組末尾的假設元素(即取消引用它,總是UB)。

你說:

@Nick我想讓它適用於任何有效的迭代器,包括結尾。 它應該是可能的,因為to_pointer1也涵蓋了這種情況。

to_pointer1 包括這種情況。 to_pointer1返回一個無效的內存地址(實際上該地址可能有效,但那里沒有數據)。

我用這個模板:

template<typename It>
inline auto ptr(It const&it) -> decltype(std::addressof(*it))
{ return std::addressof(*it); }

實際上,這適用於大多數迭代器。 例外的是其中任一對象*it沒有被定義( vector<bool>::iterator ),或者it 指向無處(而不是一個過去最最后一個元素)。 為了你的特殊目的,它應該沒問題,除了vector<bool> (當指針的概念不合理時)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM