标签: unordered-map

(auto i:unordered_map)是否保证每次都有相同的顺序?

当我std::unordered_map使用基于for循环的范围迭代两次时,顺序是否保证相等?

std::unordered_map<std::string, std::string> map;

std::string query = "INSERT INTO table (";
bool first = true;
for(auto i : map)
{
    if(first) first = false;
    else query += ", ";
    query += i.first;
}
query += ") ";

query += "VALUES (";
first = true;
for(auto i : map)
{
    if(first) first = false;
    else query += ", ";
    query += i.second;
}
query += ");"
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,结果字符串应采用该形式.因此,重要的是两个时间,迭代的顺序是相同的.

INSERT INTO table (key1, key2, key3) VALUES (value1, value2, value3);
Run Code Online (Sandbox Code Playgroud)

这是用C++保证的吗?

c++ standards for-loop unordered-map

21
推荐指数
2
解决办法
3万
查看次数

在循环中擦除unordered_map中的元素

StackOverflow上有几个答案表明以下循环是一种很好的方法来擦除std::unordered_map满足某些谓词的元素pred:

std::unordered_map<...> m;
auto it = m.begin();
while (it != m.end())
{
    if (pred(*it))
        it = m.erase(it);
    else
        ++it;
}
Run Code Online (Sandbox Code Playgroud)

我对C++ 11(而不是C++ 14)特别感兴趣,而cppreference.com上的以下不祥之处表明上述循环依赖于未定义的行为,并且可能在C++ 11中无效:

保留未擦除元素的顺序(这使得可以在迭代容器时擦除单个元素)(从C++ 14开始)

另请参见标题2356.无序关联容器中擦除的稳定性,其中包含对第754页的工作草案N3797第14项的请求的措辞更改(附加短语开头",并保留相对顺序......").

这个措辞与N3797有关.

按照指示修改[unord.req],p14:

-14- insert和emplace成员不应影响对容器元素的引用的有效性,但可能使容器的所有迭代器无效.擦除成员应仅使迭代器和对已擦除元素的引用无效,并保留未擦除元素的相对顺序.

如果我对cppreference.com的注释的解释是正确的,并且上面的循环依赖于C++ 11中的未定义行为,那么在C++ 11中解决这个问题的最有效方法是什么?

c++ unordered-map c++11

21
推荐指数
3
解决办法
4862
查看次数

哈希函数对于一对多长?

我需要将一对映射long long到a double,但我不确定要使用什么散列函数.每对可以由任意两个数字组成,但在实践中它们通常是介于0和之间的数字100(但同样,这是不可保证的).

tr1::unordered_map文档.我开始是这样的:

typedef long long Int;
typedef std::pair<Int, Int> IntPair;

struct IntPairHash {
  size_t operator(const IntPair& p) const {
    return ...; // how to hash the pair?
  }
};

struct IntPairEqual {
  bool operator(const IntPair& a, const IntPair& b) const {
    return a.first == b.first 
      && a.second == b.second;
  }
};

tr1::unordered_map<IntPair, double, IntPairHash, IntPairEqual> myMap;
Run Code Online (Sandbox Code Playgroud)

一般来说,我不知道要使用什么哈希函数.什么是一个很好的通用哈希函数?

c++ hash unordered-map hash-function tr1

19
推荐指数
3
解决办法
2万
查看次数

C++ 11:在迭代时从std :: unordered_map中删除单个元素是否安全?

考虑在迭代时从关联容器中删除元素的规范算法:

for (auto iter = myMap.begin(); iter != myMap.end(); )
{
    if (/* removal condition */)
    {
        iter = myMap.erase(iter);
    }
    else
    {
        ++iter;
    }
}
Run Code Online (Sandbox Code Playgroud)

在使用C++ 11 std::unordered_map容器时,我一直在不加思索地应用这个算法.但是,在浏览cppreference.comstd::unordered_map::erase上的文档之后,在阅读以下注释后我变得有点担心:

保留未擦除元素的顺序(这使得可以在迭代容器时擦除单个元素)(从C++ 14开始)

基于这个陈述,我假设在C++ 14标准中添加了语言,以确保库实现者在调用后保证排序std::unordered_map::erase.例如,这样的要求可能会限制实现在删除元素后不重新整理整个容器,而只是允许它从相应的存储桶中删除元素?

如果我在C++ 11中没有这样的保证,并且如果我希望我的代码是可移植的,那么如果我std::unordered_map在迭代期间删除一个元素,我是否必须担心一些元素会被访问多次或根本不访问?

c++ iterator stl unordered-map c++11

19
推荐指数
1
解决办法
1780
查看次数

pair <int,int>对作为unordered_map问题的关键

我的代码:

 typedef pair<int,int> Pair
  tr1::unordered_map<Pair,bool> h;
  h.insert(make_pair(Pair(0,0),true));
Run Code Online (Sandbox Code Playgroud)

Erorr

 undefined reference to `std::tr1::hash<std::pair<int, int> >::operator()(std::pair<int, int>) const'
Run Code Online (Sandbox Code Playgroud)

我需要修理什么?

谢谢

c++ unordered-map std-pair

17
推荐指数
2
解决办法
2万
查看次数

使用unordered_map的模板代码膨胀

我想知道是否unordered_map使用类型擦除实现,因为unordered_map<Key, A*>并且unordered_map<Key, B*>可以使用完全相同的代码(除了强制转换,这是机器代码中的无操作).也就是说,两者的实现可以基于unordered_map<Key, void*>保存代码大小.

更新:此技术通常被称为精简模板成语(感谢下面的评论者指出这一点).

更新2:我对Howard Hinnant的观点特别感兴趣.我希望他读到这个.

所以我写了这个小测试:

#include <iostream>

#if BOOST
# include <boost/unordered_map.hpp>
  using boost::unordered_map;
#else
# include <unordered_map>
  using std::unordered_map;
#endif

struct A { A(int x) : x(x) {} int x; };
struct B { B(int x) : x(x) {} int x; };

int main()
{
#if SMALL
    unordered_map<std::string, void*> ma, mb;
#else
    unordered_map<std::string, A*> ma;
    unordered_map<std::string, B*> mb;
#endif

    ma["foo"] = new …
Run Code Online (Sandbox Code Playgroud)

c++ boost unordered-map type-erasure libc++

17
推荐指数
1
解决办法
796
查看次数

如何在迭代时从无序地图中删除多个项目?

请考虑以下情况:

using namespace std;
unordered_map<int, vector<A>> elements;
Run Code Online (Sandbox Code Playgroud)

现在我正在迭代这个无序的地图:

for (auto it = elements.begin(); it != elements.end(); ++it)
Run Code Online (Sandbox Code Playgroud)

在循环内部,我正在形成几个元素elements(当前的一个it指向和更多的元素,不一定是那些在线的那些!).因为每个元素只能是一个集群的一部分,所以我想从地图中删除它们,然后继续下一个元素(即构建下一个集群).

我怎么能这样做并仍然在正确的位置继续迭代?

c++ iterator unordered-map

17
推荐指数
3
解决办法
1万
查看次数

你什么时候使用std :: unordered_map :: emplace_hint?

我知道如何使用std::unordered_map::emplace,但我该如何使用emplace_hintcpluspluscppreference都没有提供一组示例来说明我们如何知道放置元素的位置.

任何人都可以提供一些有关这方面的信息,或者提供一些示例/插图,告诉我们什么时候可以知道布置元素应该去哪里?

c++ stl unordered-map c++11

17
推荐指数
1
解决办法
3085
查看次数

unordered_map 对哈希函数的过度调用

以下代码导致对哈希函数的无法解释的调用:

namespace foo {
    using Position = tuple <int, int, int>;
    
    std::ostream& operator<<(std::ostream& out, const Position& pos) noexcept{
        return out << get<0>(pos) << ", " << get<1>(pos) << ", " << get<2>(pos);
    }

    struct hashFunc{
        std::size_t operator()(const Position& pos) const noexcept{
            int res = get<0>(pos) * 17 ^ get<1>(pos) * 11 ^ get<2>(pos);
            cout << "@@@ hash function called for key: " << pos 
                 << ", hash: " << res << endl;
            return res;
        }
    };

    template<typename T>
    void print_buckets(T&& …
Run Code Online (Sandbox Code Playgroud)

c++ unordered-map

17
推荐指数
2
解决办法
326
查看次数

unordered_multimap - 迭代find()的结果产生具有不同值的元素

C++中的multimap看起来很奇怪,我想知道为什么

#include <iostream>
#include <unordered_map>

using namespace std;

typedef unordered_multimap<char,int> MyMap;

int main(int argc, char **argv)
{
    MyMap map;
    map.insert(MyMap::value_type('a', 1));
    map.insert(MyMap::value_type('b', 2));
    map.insert(MyMap::value_type('c', 3));
    map.insert(MyMap::value_type('d', 4));
    map.insert(MyMap::value_type('a', 7));
    map.insert(MyMap::value_type('b', 18));

    for(auto it = map.begin(); it != map.end(); it++) {
        cout << it->first << '\t';
        cout << it->second << endl;
    }

    cout << "all values to a" << endl;
    for(auto it = map.find('a'); it != map.end(); it++) {
        cout << it->first << '\t' << it->second << endl;
    }

}
Run Code Online (Sandbox Code Playgroud)

这是输出: …

c++ iteration stl unordered-map c++11

15
推荐指数
3
解决办法
2万
查看次数