STL容器的常见模式是:
map<Key, Value> map;
for(map<Key, Value>::iterator iter = map.begin(); iter != map.end(); ++iter)
{
...
}
因此,为了避免编写模板参数的声明,我们可以在某处执行此操作:
typedef map<Key, Value> TNiceNameForAMap;
但是如果这个映射仅用于单个函数或单个迭代,则这是一个烦人的开销。
这种typedef有什么方法吗?
答案 0 :(得分:10)
不确定“开销”是什么意思。如果它简化了你编写代码的方式,那就使用它,否则坚持使用简写。
如果它仅在限制范围内使用,请将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();
}
不错。
答案 1 :(得分:5)
您可以使用Boost.Foreach
答案 2 :(得分:3)
C ++标准的未来版本(称为C++0x)将引入new use for the auto
keyword,允许您编写如下内容:
map<Key, Value> map;
for(auto iter = map.begin(); iter != map.end(); ++iter)
{
...
}
答案 3 :(得分:2)
我个人认为 MYMAP :: iterator 比 map&lt; int,string&gt; :: iterator 甚至 std :: map&lt; int,std更具可读性:: string&gt; :: iterator 所以我总是做typedef。唯一的开销是一行代码。
编译代码后,可执行文件的大小或速度没有差异。这只是可读性。
答案 4 :(得分:0)
如果typedef是单个函数的本地函数,则它甚至不需要是 nice 名称。使用X或MAP,就像在模板中一样。
答案 5 :(得分:0)
C ++ 0x还将提供基于范围的for循环,类似于迭代循环用于其他语言。
不幸的是,GCC尚未实现基于范围的(但 实现自动)。
编辑:同时,还要考虑键入解码迭代器。它没有绕过一次使用的typedef(除非你把它放在一个标题中,这总是一个选项),但是它使得结果代码缩短了一个:: iterator。
答案 6 :(得分:0)
在过去的几年里,我真的试图摆脱使用手动编写的循环而不是使用STL算法。您的上述代码可以更改为:
struct DoLoopBody {
template <typename ValueType>
inline void operator()(ValueType v) const {
// ...
}
};
std::for_each (map.begin(), map.end(), DoLoopBody ());
不幸的是,DoLoopBody类不能是本地类,这通常被强调为缺点。但是,我认为这是一个优势,因为循环体现在可以单独进行单元测试。