像容器typedef的STL快捷方式?

时间:2020-03-06 14:38:25  来源:igfitidea点击:

STL容器的常见模式是:

map<Key, Value> map;
for(map<Key, Value>::iterator iter = map.begin(); iter != map.end(); ++iter)
{
  ...
}

因此,为了避免编写模板参数的声明,我们可以在某个地方执行此操作:

typedef map<Key, Value> TNiceNameForAMap;

但是,如果仅将此映射用于单个函数或者单个迭代,则这将是一个烦人的开销。

有什么办法可以解决这个typedef吗?

解决方案

不知道我们所说的"开销"是什么意思。如果它简化了编写代码的方式,请使用它,否则请长期使用。

如果仅在受限范围内使用,则将typedef放在同一范围内。这样就不必发布,记录或者在任何UML图上显示它。例如(在其他方面,我不认为这是最好的代码):

int totalSize() {
    typedef std::map<Key, Value> DeDuplicator;
    DeDuplicator everything;

    // Run around the universe finding everything. If we encounter a key
    // more than once it's only added once.

    // now compute the total
    int total = 0;
    for(DeDuplicator::iterator i = everything.begin(); i <= everything.end(); ++i) {
        total += i->second.size(); // yeah, yeah, overflow. Whatever.
    }
    return total;
}

结合Ferruccio的建议(如果我们使用的是Boost),循环将变为:

BOOST_FOREACH(DeDuplicator::pair p, everything) {
    total += p.second.size();
}

并结合bk1e的建议(如果我们使用的是C ++ 0x或者具有其功能),并假定BOOST_FOREACH与auto交互的方式我认为应该基于以下事实:它通常可以处理对兼容类型的隐式强制转换:

std::map<Key, Value> everything;
// snipped code to run around...
int total = 0;
BOOST_FOREACH(auto p, everything) {
    total += p.second.size();
}

不错。

我们可以使用Boost.Foreach

我个人认为MYMAP :: iterator比map <int,string> :: iterator甚至std :: map <int,std :: string> :: iterator更具可读性,所以我总是做typedef。唯一的开销是一行代码。

编译代码后,可执行文件的大小或者速度将没有差异。这只是关于可读性。

C ++标准的未来版本(称为C ++ 0x)将为auto关键字引入新用法,使我们可以编写如下内容:

map<Key, Value> map;
for(auto iter = map.begin(); iter != map.end(); ++iter)
{
  ...
}

如果typedef是单个函数的局部变量,则甚至不必是一个好名字。就像在模板中一样,使用X或者MAP。

C ++ 0x也将提供基于范围的for循环,这与其他语言中的循环迭代类似。

不幸的是,GCC尚未实现基于范围的(但实现了自动)。

编辑:同时,还考虑对迭代器进行类型定义。它无法解决一次性使用的typedef(除非我们将其放在标头中,这始终是一个选项),但是它会使生成的代码缩短一个:: iterator。

在过去的几年中,我确实尝试过使用手动编写的循环,而不是使用STL算法。我们上面的代码可以更改为:

struct DoLoopBody {
  template <typename ValueType>
  inline void operator()(ValueType v) const {
    // ...
  }
};

std::for_each (map.begin(), map.end(), DoLoopBody ());

不幸的是,类DoLoopBody不能是本地类,这通常被强调为缺点。但是,我认为这是一个优势,因为现在可以单独对循环的主体进行单元测试了。