![](/img/trans.png)
[英]std::remove() works as expected with literal but not with dereferenced iterator
[英]Accessing an std::set via a dereferenced iterator
考慮:
#include <stdio.h>
#include <set>
void printset(std::set<int>& Set) {
for (std::set<int>::iterator siter = Set.begin(); siter != Set.end(); ++siter) {
int val = *siter;
printf("%d ", val);
}
}
void printsetofset0(std::set<std::set<int>>& SetofSet) {
for (std::set<std::set<int>>::iterator siter = SetofSet.begin(); siter != SetofSet.end(); ++siter) {
std::set<int> Set = *siter;
printset(Set);
}
}
void printsetofset1(std::set<std::set<int>>& SetofSet) {
for (std::set<std::set<int>>::iterator siter = SetofSet.begin(); siter != SetofSet.end(); ++siter) {
printset(*siter);//this line gives error
}
}
printsetofset1
與printset(*siter);
給出錯誤:
<source>: In function 'void printsetofset1(std::set<std::set<int> >&)':
<source>:20:34: error: binding reference of type 'std::set<int>&' to 'const std::set<int>' discards qualifiers
20 | printset(*siter);
| ^~~~~~
<source>:4:38: note: initializing argument 1 of 'void printset(std::set<int>&)'
4 | void printset(std::set<int>& Set) {
| ~~~~~~~~~~~~~~~^~~
Compiler returned: 1
請在此處查看 Godbolt 鏈接。
printsetofset0
與行: std::set<int> Set = *siter; printset(Set);
std::set<int> Set = *siter; printset(Set);
編譯並工作得很好。
為什么一個printsetofset0
有效,而看似功能相同(且更短) preintsetofset1
卻不起作用?
迭代器指向的元素是常量。 您可以在注釋中閱讀它:因為 iterator 和 const_iterator 都是常量迭代器(實際上可能是同一類型),所以不可能通過這些成員函數中的任何一個返回的迭代器來改變容器的元素。 . 但是,傳遞對printset
function 的引用將違反此屬性。
在內部,集合允許通過索引結構進行快速訪問。 更改元素需要重新排序集合(內部)。
您可以通過向printset
function 的參數添加const
修飾符來解決這種情況:
void printset(const std::set<int>& Set)
你所有的打印函數都應該通過 const 引用來獲取它們的參數,因為它們不需要修改參數。 像這樣:
void printset(const std::set<int>& Set)
我還建議使用基於范圍的 for 循環來簡化您的代碼:
for (int val : Set)
printset
不能采用非常量引用的原因是您將其傳遞給集合中的集合,並且存儲在集合中的值始終是 const。 有關更多信息,請參閱: Why does std::set seem to force the use of a const_iterator?
問題在於,盡管集合類型同時定義了iterator
和const_iterator
類型,但這兩種類型的迭代器都為我們提供了對集合中元素的只讀訪問權限。 也就是說,集合中的鍵是const
。 我們可以使用集合迭代器來讀取而不是寫入元素的值。
因此,要解決程序中的錯誤,您需要向printSet
function 的名為Set
的參數添加一個低級常量,如下所示:
//------------vvvvv--------------------------->low-level const added here
void printset(const std::set<int>& Set) {
//other code as before
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.