【问题标题】:Optimizing initialization on maps: forwarding the key优化地图初始化:转发密钥
【发布时间】:2013-11-15 16:15:42
【问题描述】:

我有一个应该很有趣的问题。我想在构造时“转发初始化std::unordered_map 中的一个项目。

这些是细节。我有一个从std::string 到自定义类prop 的哈希映射,在我的梦中,它会初始化一个成员变量,计算字符串传递给 std::unordered_map::operator[] 的哈希。 p>

这是我编写的一个方便的代码,但我不知道从哪里开始。

为什么会这样?因为我想避免类似“如果字符串不在容器中计算哈希;用prop 做事”。避免这种if 可能会影响我的表现。因此,当地图在容器中添加新项目时,构造函数以及散列将只执行一次。会很棒的。

有什么提示吗?

感谢和干杯!

#include <iostream>
#include <string>
#include <unordered_map>

class prop
{
public:
    prop(std::string s = "") : s_(s), hash_(std::hash<std::string>()(s))
    {
        // Automagically forwarding the string in the unordered_map...
    };

    std::string s_;
    std::size_t hash_;
    int x;
};

int main(int argc, const char * argv[])
{
    // Forward the std::string to the prop constructor... but how?
    std::unordered_map<std::string, prop> map;

    map["ABC"].x = 1;
    map["DEF"].x = 2;
    map["GHI"].x = 3;
    map["GHI"].x = 9; // This should not call the constructor: the hash is there already

    std::cout << map["ABC"].x << " : " << map["ABC"].s_ << " : " << map["ABC"].hash_ << std::endl;
    std::cout << map["DEF"].x << " : " << map["DEF"].s_ << " : " << map["DEF"].hash_ << std::endl;
    std::cout << map["GHI"].x << " : " << map["GHI"].s_ << " : " << map["GHI"].hash_ << std::endl;

    std::cout << map["XXX"].x << " : " << map["XXX"].s_ << " : " << map["XXX"].hash_ << std::endl;

    return 0;
}

【问题讨论】:

  • 为什么不将prop 存储在std::unordered_set 中,并使用适当的hash 和相等操作?
  • 我可以更换容器,但是如何避免使用讨厌的if?这不仅仅是我需要该哈希的相等性。在一个实际的类中,我将存储从给定字符串计算的 K 哈希值。
  • 我想你应该看看 C++14 即将推出的特性,比如基于不同值查找元素。请参阅 C++14 的 std::unordered_set::find

标签: c++ c++11 hashmap initialization unordered-map


【解决方案1】:

只需使用您的道具类作为键,而不是字符串:

#include <iostream>
#include <string>
#include <unordered_map>

class prop
{
public:
    prop(std::string s = "") : s_(s), hash_(std::hash<std::string>()(s))
    {
        // Automagically forwarding the string in the unordered_map...
    };

    std::string s_;
    std::size_t hash_;
};

int main(int argc, const char * argv[])
{
    // Forward the std::string to the prop constructor... but how?
    std::unordered_map<prop, int, ...> map( ... );

    prop pABC( "ABC" ), pDEF( "DEF" ), pGHI( "GHI" );

    map[pABC] = 1;
    map[pDEF] = 2;
    map[pGHI] = 3;
    map[pGHI] = 9; 

    std::cout << map[pABC] << " : " << pABC.s_ << " : " << pABC.hash_ << std::endl;
    std::cout << map[pDEF] << " : " << pDEF.s_ << " : " << pDEF.hash_ << std::endl;
    std::cout << map[pGHI] << " : " << pGHI.s_ << " : " << pGHI.hash_ << std::endl;

    prop pXXX( "XXX" );
    std::cout << map[pXXX] << " : " << pXXX.s_ << " : " << pXXX.hash_ << std::endl;

    return 0;
}

我省略了自定义哈希和比较函数,没有它的想法应该很清楚。

【讨论】:

  • 那真是太好了。除了我的数学建模。我想要一张地图M : string -&gt; prop,例如,你建议用它的双重M* : prop -&gt; string 来模拟我的问题。不容易辩解,但可以接受!
猜你喜欢
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2019-11-02
  • 2012-07-24
  • 2018-06-23
  • 2020-12-31
  • 1970-01-01
相关资源
最近更新 更多