[英]return pointer rather than vector::iterator and convert vector::iterator to pointer
[英]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.