[英]Why does std::copy() require std::back_inserter to insert into a vector with sufficient capacity?
[英]Why does std::insert require CopyConstructibility?
為什么此代碼不起作用? 對於std :: map的insert方法,文檔中沒有關於CopyConstructibility的內容: http ://en.cppreference.com/w/cpp/container/map/insert
我可以構造std :: pair,第二個元素是我的non_copyable類,但是即使insert方法的第一個重載采用const value_type&,也無法將其插入到map中,所以應該可以正常工作。
有人可以幫助我了解為什么std :: map需要此CopyConstructibility嗎?
#include <utility>
#include <map>
struct non_copyable {
non_copyable(){}
private:
non_copyable(const non_copyable&);
};
int main() {
std::pair<int, non_copyable> p; // this works!
std::map<int, non_copyable> m;
m.insert(std::pair<int, non_copyable>()); // this does NOT work
}
...即使insert方法的第一個重載采用const value_type& ,所以也可以正常工作。
不,實際上,在這種情況下,正確的過載解決方案候選對象是:
m.insert(std::pair<int, non_copyable>());
這是重載的成員函數:
template< class P >
std::pair<iterator,bool> insert( P&& value );
現在, 此頁面描述了為什么它不起作用:
...僅在
std::is_constructible<value_type, P&&>::value == true
參與重載解析。
您的non_copyable
不可構造:
using M = std::map<int, non_copyable>;
using P = std::pair<int, non_copyable>;
std::is_constructible<M::value_type, P&&>::value; // false
因為沒有可用的構造函數,包括由編譯器生成的默認隱式move構造函數。
non_copyable
甚至禁用其默認的隱式move構造函數的原因是,由於具有用戶定義的副本構造函數,如文檔所述 :
如果沒有為類類型(struct,class或union)提供用戶定義的move構造函數,則以下所有條件均成立:
沒有用戶聲明的副本構造函數
沒有用戶聲明的副本分配運算符
沒有用戶聲明的移動分配運算符
沒有用戶聲明的析構函數
現在給non_copyable
一個move構造函數成為您的責任:
struct non_copyable {
non_copyable(){}
non_copyable(non_copyable &&) = default;
private:
non_copyable(const non_copyable&);
};
您可能會感興趣,為什么您根本不需要制作任何副本,因此即使您可以在地圖內部直接構造(成對)對,也要提供可構造副本的類型。
這是因為要提供所需的性能,通常將std :: map的內部表示形式實現為平衡的二進制搜索樹(最終作為具有相似性能特征的另一個數據結構),這需要存儲元素的某些特定順序。 因此,在添加或刪除某些元素之后,該順序可能會中斷,並且為了保持其正確性,有時需要存儲的元素進行內部移動。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.