C ++模板类映射

时间:2011-12-07 11:16:01

标签: c++ templates map iterator

我将构造函数和两个函数添加到我之前链接的问题C++ iterate through a template Map的类中,在这一点上我需要帮助:

  • 你认为这个构造函数有什么作用?
  • 在地图的开头添加一个值?
  • 我在相应的键中看到,虽然在main中初始化后只有一个地址作为值。怎么了?

operator []应该获取特定键的值。但是我无法使用它以便在输出中获取地图的元素。任何提示?

template<class K, class V>
class template_map{
public:
    template_map( V const& val) {
        m_map.insert(my_map.begin(),std::make_pair(std::numeric_limits<K>::min(),val));
    };    

    typedef typename std::map<K,V> TMap;

    TMap my_map;
    typedef typename TMap::const_iterator const_iterator;
    const_iterator begin() const { return my_map.begin(); }
    const_iterator end() const   { return my_map.end(); }
    V const& operator[]( K const& key ) const {
        return ( --my_map.upper_bound(key) )->second;
    }

    ...
};

int main()
{
    interval_map<int,int> Map1 (10);
    //Show the elements of the map?
}

还要考虑它应该是一个将值插入地图的函数。

3 个答案:

答案 0 :(得分:1)

  

你认为这个构造函数有什么作用?在。添加一个值   地图的开头?我在相应的键中只看到一个地址   在main中初始化后的值。有什么问题?

它将这一个值添加到地图中。迭代器参数只是一个提示:如果要在此位置之后插入新项目,则可以更快地完成操作。否则,地图将需要找到正常插入新值的正确位置。

  

operator []应该获取特定键的值。   但是我无法使用它来获取地图中的元素   输出。任何提示?

upper_bound将迭代器返回到第一个键值对,其中key大于参数。因此,--upper_bound返回项的迭代器,其键的大小等于或小于查询的键。如果upper_bound返回map.begin(),因为所有键都大于查询,则递减它是未定义的行为。

这里需要的是find成员函数。您还需要处理未找到密钥的情况(返回map.end()),例如通过抛出异常。

或者,您可以operator[]来实施map::operator[]。这意味着该函数不能是const,因为如果找不到该键,map会插入一个新的默认值。

答案 1 :(得分:1)

map::insert()中的迭代器只是提示;从本质上讲,它对程序的语义没有任何意义。

您的代码将通过构造函数参数传递的值与键numeric_limits<K>::min()一起插入,即给定键类型的最小可能值。只有当numeric_limits专门用于K类型时,才会强制执行。

另请注意,如果密钥已存在,则相应的映射值将被覆盖,因此相应的插入函数的使用非常有限。

答案 2 :(得分:1)

  

你认为这个构造函数有什么作用?在地图的开头添加一个值?

它会初始化地图,以便map[x] == v代替任何x。该映射将间隔与值相关联,在内部存储由每个间隔的开始键控的法线映射;它被初始化,以便键类型的整个范围映射到初始值。

  

我在相应的键中看到虽然在main中初始化后只有一个地址作为值。怎么了? operator []应该获取特定键的值。但是我无法使用它以便在输出中获取地图的元素。任何提示?

我不知道你在那里问什么。例如,如果您尝试cout << Map1[42] << '\n';,那么您的程序应输出10,因为这是分配给整个整数范围的初始值。

  

还要考虑它应该是一个将值插入地图的函数。

由于内部地图是公开的,您可以使用

向地图添加新的间隔
Map1.my_map.insert(std::make_pair(interval_start, value));

my_map设为私有可能更有礼貌,并提供insert()功能来执行此操作。你可以还添加一个非{const}重载operator[],它会插入一个新范围并返回对其值的引用,如

V & operator[](K const & key) {
    V const & old_value = (--my_map.upper_bound(key))->second;
    return *my_map.insert(std::make_pair(key, old_value)).first;
}

虽然这可能不是一个好主意,但是你必须要小心,当你只想读取值时,不要意外地插入许多范围。

  

我的问题是如何遍历地图以获取其所有元素并将其打印在main中。它显示了一个带有对象初始化值的地址。

记住地图上的迭代器引用了一个键/值对(类型为std::pair<K,V>),你应该可以像这样在地图上迭代:

for (auto it = Map1.begin(); it != Map1.end(); ++it) {
    std::cout << it->first << " maps to " << it->second << '\n';
}

(在C ++ 03中,您需要编写template_map<int,int>::const_iterator而不是auto)。