![](/img/trans.png)
[英]Why does a class used as a value in a STL map need a default constructor in …?
[英]How should std::map be used with a value that does not have a default constructor?
我有一個我想要放入地圖的值類型。 它有一個很好的默認復制構造函數,但沒有默認的構造函數。
我相信只要我遠離使用operator[]
,一切都會好的。
但是我最終得到了像這樣的非常丑陋的結構來實際插入一個對象。 (我認為如果已經存在該鍵的值,則插入失敗)。
// equivalent to m[5]=x but without default construction
std::map<int,X>::iterator it = m.find(5);
if( it != m.end() )
{
m->second = x;
}
else
{
m->insert( std::make_pair(5,x) );
}
我相信它會掃描地圖兩次,看起來也很難看。
是否有更簡潔/更有效的方法來做到這一點?
您可以先獲取插入帶有lower_bound
的對的位置,然后檢查它是否已經存在,如果沒有,請插入它,提供迭代器插入位置。 沿着那條線的東西。
您可以使用標准insert
函數簡單地“插入或覆蓋”:
auto p = mymap.insert(std::make_pair(key, new_value));
if (!p.second) p.first->second = new_value; // overwrite value if key already exists
如果要通過重新引用傳遞元素,請使該對顯式:
insert(std::pair<K&, V&>(key, value));
如果你有map_t
這樣的地圖的typedef,你可以說std::pair<map_t::key_type &, map_t::mapped_type &>
,或者這個主題的任何合適的變體。
也許這最好包裝成一個幫手:
template <typename Map>
void insert_forcefully(Map & m,
typename Map::key_type const & key,
typename Map::mapped_type const & value)
{
std::pair<typename Map::iterator, bool> p = m.insert(std::pair<typename Map::key_type const &, typename Map::mapped_type const &>(key, value));
if (!p.second) { p.first->second = value; }
}
你在map
界面中遺漏了兩件事(等等):
insert(value_type)
返回一個std::pair<iterator, bool>
的.first
構件指向與你試圖插入鍵和所述元件.second
構件表明它是否實際上是你試圖插入的元件或另一種以前是在容器里。 insert(iterator, value_type)
允許您提供有關insert的位置的提示 后者在你的情況下並不一定有用。
typedef std::map<int,X> Map;
// insert and check
std::pair<Map::iterator, bool> const result =
map.insert(std::make_pair(5, x)); // O(log N)
if (not result.second)
{
result->first.second = x; // O(1)
// OR
using std::swap;
swap(result->first.second, x);
}
如果你輸入的類型不支持賦值而且沒有交換,那么你需要咬緊牙關:
// locate and insert
Map::iterator position = map.lower_bound(5); // O(log N)
if (position != map.end() and position->first == 5)
{
position = map.erase(position); // O(1)
}
map.insert(position, std::make_pair(5, x)); // O(log N) if rebalancing
在C ++ 11中, insert
方法加倍:
insert(value_type const&)
//按副本插入 insert(P&&)
//通過移動插入 並且通過完美的轉發我們得到了新的emplace
方法。 與insert類似,但通過將參數轉發給其構造函數來構造元素。 它如何區分關鍵和價值的論點對我來說是一個謎。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.