【问题标题】:C++ template class mapC++模板类映射
【发布时间】:2012-01-14 21:53:36
【问题描述】:

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

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

运算符 [] 应该获取特定键的值。但是我不能使用它来获取输出中的地图元素。有什么提示吗?

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?
}

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

【问题讨论】:

    标签: c++ templates map iterator


    【解决方案1】:

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

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

    运算符 [] 应该获取特定键的值。 但是我不能使用它来获取地图中的元素 输出。有什么提示吗?

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

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

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

    【讨论】:

      【解决方案2】:

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

      您的代码将通过构造函数参数传递的值与键 numeric_limits&lt;K&gt;::min() 一起插入,即给定键类型的最小可能值。这只有在 numeric_limits 专门用于 K 类型时才会编译。

      还要注意,如果键已经存在,则对应的映射值将不会被覆盖,因此相应的插入函数的用途将非常有限。

      【讨论】:

      • 难道不能创建一个函数来擦除已经存在的键并添加新的键吗?这就是我打算做的。
      • @arjacsoh:是的,当然。我什至不会删除元素;我只是覆盖这个值。 This previous answer 甚至展示了如何:-)
      【解决方案3】:

      你认为这个构造函数是做什么的?在 map 的开头添加一个值?

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

      我看到虽然在各自的键中只有一个地址作为在 main 中初始化后的值。怎么了?运算符 [] 应该获取特定键的值。但是我不能使用它来获取输出中的地图元素。有什么提示吗?

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

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

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

      给地图添加一个新的区间
      Map1.my_map.insert(std::make_pair(interval_start, value));
      

      my_map 设为私有可能更礼貌,并提供insert() 函数来执行此操作。您还可以添加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.js 中打印它们。它向我显示了一个带有对象初始化值的地址。

      记住映射上的迭代器指的是键/值对(std::pair&lt;K,V&gt; 类型),您应该能够像这样在映射上进行迭代:

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

      (在 C++03 中,您需要编写 template_map&lt;int,int&gt;::const_iterator 而不是 auto)。

      【讨论】:

      • 我的问题是如何遍历地图以获取其所有元素并在 main.js 中打印它们。它向我显示了一个带有对象初始化值的地址。
      • @arjacsoh:那么也许你应该在你的问题中提到这一点,展示你正在做什么以获得“具有对象初始化值的地址”,无论这意味着什么。我在答案中添加了一个迭代示例。
      • 这就是我所做的,但我想使用运算符对 Map1[i] 做同样的事情。
      • @arjacsoh:你不能这样做,因为这个映射旨在为 所有 可能的键值提供一个值 - i 的值集也是大到可以合理地迭代,尤其是对于打印结果。您可以使用迭代器对地图定义的区间进行迭代。
      猜你喜欢
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      相关资源
      最近更新 更多