2008-09-24 46 views
1

与STL容器一个常见的模式是这样的:STL像容器typedef的快捷方式?

map<Key, Value> map; 
for(map<Key, Value>::iterator iter = map.begin(); iter != map.end(); ++iter) 
{ 
    ... 
} 
为了避免写模板参数的声明,我们可以做到这一点的地方

所以:

typedef map<Key, Value> TNiceNameForAMap; 

但是,如果这个地图只是使用在单个函数中或单个迭代中,这是一个令人讨厌的开销。

有没有办法绕过这个typedef?

回答

10

不确定您的意思是“开销”。如果它简化了你写代码的方式,使用它,否则坚持使用longhand。

如果它仅用于受限制的范围,则将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; 
} 

与费鲁乔的建议合并(如果你使用升压),循环变为:

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

并结合bk1e的建议(如果您使用C++ 0x或具有它的功能),并假设BOOST_FOREACH与自动进行交互的方式,我认为它应该基于它可以正常处理隐式强制转换以兼容类型:

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

不错。

+1

干得好!您的最后一个符合*和*可读性的Python级别。 – rlerallut 2008-09-25 22:41:19

+0

甚至可能跑得更快。 – 2008-09-25 23:21:28

5

您可以使用Boost.Foreach

+0

良好的调用,因为循环详细程度大于typedef详细程度... – 2008-09-24 03:32:33

+1

是的,最好的部分是语法是足够相似的C++ 0x foreach构造,你应该能够更新您的代码与正则表达式搜索和替换当你的编译器支持。 – Ferruccio 2008-09-26 11:26:25

2

我个人认为MYMAP:迭代地图< INT更具可读性,串>:迭代甚至的std ::地图< INT,的std :: string > ::迭代器所以我总是做typedef。唯一的开销是一行代码。

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

3

C++标准(被称为C++0x)的未来版本将引入new use for the auto keyword,让你写的东西像下面这样:如果typedef的是本地的一个单一的功能它不

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

呜呼!强烈的打字就像它应该。 – 2008-09-24 12:31:15

0

甚至需要一个不错的名称。使用X或MAP,就像在模板中一样。

0

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

不幸的是,GCC还没有实现基于范围的(但是确实实现自动)。

编辑:同时,也考虑typedefing迭代器。它没有绕过一次使用的typedef(除非你把它放在一个头文件中,这总是一个选项),但是它使得得到的代码缩短了一个:: iterator。

0

在过去的几年里,我真的试图摆脱使用手动编写的循环,而不是使用STL算法。你上面的代码可以改为:

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

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

不幸的是,类DoLoopBody不能是局部类,这往往强调是一个缺点。不过,我认为这是一个优势,因为循环的主体现在可以单独进行单元测试。