“现代C ++”的实例?

我一直在使用更多的“现代”c ++结构,但表面上并不是无处不在。 我正在寻找开源项目来研究现代C ++和STL用法的很好的例子。

像Meyer的“Effective STL”中提到的那样,例如试图避免循环并用更多的函数结构replace它们,使用boost :: bind和boost :: function等。这些对我来说仍然有点不自然,当我必须快速完成某些工作时,我倾向于退回到libc和string.h(当我从寒冷的手中撬出来的时候,可以准备好我的工作)。

不过,我也有积极的经验,发现什么是简化的剧烈变化,因为我已经使用了这些构造,或者能够用几行代码来实现,因为我有正确的操作符和函数。 另外,我最近一直在关注并发性,所以这对我来说变得更加重要。

您能否推荐一些精心编写的开源项目的例子,这些项目大量使用了STL和其他可以学习的现代c ++技术? 我特别感兴趣的应用程序代码,浏览boost源已经很有帮助,但它是必要的非常一般,因为它是库代码。

我对中型到大型项目感兴趣,至less有几万行。 find长达几百行的示例非常简单,但这不是太有用。

在这里,您可以find一些有关如何在开源项目中使用Boost的有趣示例:
http://www.boost.org/users/uses_open.html

梅耶斯是好的,但是,如果你真的想推动自己,你必须阅读

Andrei Alexandrescu – 现代C ++devise:应用generics编程和devise模式

这会打击你的头脑。 你在书中学到的东西描述了Loki图书馆 。

我最喜欢的是inttypes的转换:

 template <int v> struct Int2Type { enum { value = v }; }; 

我在过去曾经使用它来为C ++ XML serilisation库预先分配vector <>,然后加载数据:

 // We want to call reserve on STL containers that provide that function, // namely std::vector. // However, we would get a compiler error if we tried to call reserve on // a STL container that // did not provide this function. This is the solution. template <bool b, class T> class CReserve { public: static void reserve(T &lst, const int &n) { reserve(lst, n, Loki::Int2Type<b>()); } private: static void reserve(T &lst, const int &n, Loki::Int2Type<true>) { lst.reserve(n); } static void reserve(T &lst, const int &n, Loki::Int2Type<false>) { (void)lst; (void)n; } }; 

注意上面的私人专业。 那么如果你仔细观察一下,一个叫reserve(),另一个不叫。 这是一个使用bool作为types的模板专门化。

其中内部使用:

 template <bool bCallReserve, class T> bool STLSerializeClassType(MSXML::IXMLDOMNodePtr pCurNode, T &lst, CXmlArchive &archive, const char *name) { if(archive.IsStoring()) { ... } else { lst.clear(); T::size_type nCount(0); XML_ELEMENT(nCount); CReserve<bCallReserve, T>::reserve(lst, nCount); while(nCount--) { T::value_type temp; temp.SerializeXml(archive, pCurNode); lst.push_back(temp); } } } 

为了让用户的C ++代码变得简单,我添加了很多帮助器定义

 #define SERIALIZE_XML_STL_CLASS(list_name, bCallReserve) \ (HS::STLSerializeClassType<(bCallReserve)> (pCurNode, (list_name), archive, (#list_name)) ) 

所以在你的代码中你会使用类似于:

 std::list<CFred> fredList; SERIALIZE_XML_STL_CLASS(fredList, false); 

或向量:

 vector<CFred> fredList; SERIALIZE_XML_STL_CLASS(fredList, true); 

无论如何,我会停止嘲笑…这只是把简单的Int2Type <>模板很好的使用。 有很多聪明的东西,比如让编译器事先巧妙地使用枚举来计算大量的东西。 真正awsome书。

其实,我看了一下谷歌浏览器,并会推荐它。 Google的C ++编码准则对于大型项目来说是一个很好的脚手架。 他们也在我们的团队中使用/采用。 而且,我很高兴他们提供C ++ 模拟和testing框架作为开源项目。 非常方便的大型项目,你错过了很多来自Java /托pipe世界的好东西。

不是真的项目,但这里有几个片段:

boost :: thread / boost :: bind的示例使用:

 class X { void expensive_operation( int argument ); }; int main() { X x; boost::thread thr( boost::bind( &X::expensive_operation, &x, 1000 ) ); std::cout << "Thread is processing..." << std::endl; thr.join(); } 

std :: copy,std :: transform,BOOST_FOREACH:

 int main() { std::vector<std::string> v; std::copy( std::istream_iterator<std::string>( std::cin ), std::istream_iterator<std::string>(), std::back_inserter(v) ); BOOST_FOREACH( std::string & s, v ) { transform(s.begin(), s.end(), s.begin(), toupper); } std::copy( v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, " ") ); } 

片段将从用户input中读取一组string到一个向量中。 然后,对于向量中的每个string,它将转换为大写,最后输出结果。

我们的应用程序大量使用boost :: signals和boost :: function来分离那些时间不重要的类,主要是在UI类中:

 class ContactDetailPanel; class ContactListPanel { public: void update(); void edit_completed( bool change ); boost::function< void ( Contact & ) >& edit_contact(); }; int main() { ContactListPanel clp; ContactDetailPanel cdp; clp.edit_contact() = boost::bind( &ContactDetailPanel::edit, &cdp, _1 ); cdp.edit_completed() = boost::bind( &ContactListPanel::edit_completed, &clp, _1 ); ui::signal_update().connect( boost::bind( &ContactListPanel::update, &clp ) ); } 

每个面板都没有关于其他面板的信息。 将面板绑定在一起的代码具有stream程知识(编辑联系人使用联系人详细面板,通知编辑完成到联系人列表面板)。 此外,还有一个全局信号来通知面板模型的更新。

当你需要编写testing代码时,这是特别有用的。 没有必要实施模拟类来replacetesting的工作代码。 testing只是实例化类,并将函数/信号连接到testing代码而没有经过testing的类注意到,遵循testing期间最小入侵的原则。

我不确定“写得好”,但是有一些像Hypertable和KFS这样的系统级软件,它们都广泛使用Boost和STL。

我听说过有关OpenOffice和Google Chrome的一些事情,但是我没有看过他们的源代码来了解他们使用STL的准确程度。 我曾经在KDE上偷看过,但是我不一定会称之为现代的C ++。 我可以告诉你,我正在做的一些代码正在做很多现代的C ++,但是它不是开源的 – 尽pipe我认为现代C ++方法的出现和更多的开源项目只是时间和耐心的问题采用成语。

在过去的几年中,Adobe已经发布了大量的现代C ++开源代码,可能值得一试:

http://opensource.adobe.com/wiki/display/site/Home

我相信他们的GIL库已经或正在被添加到Boost中。 他们的STLab包含了很多的function,从我看到的非常干净,非常多的STL风格。

这是一个将string向量连接成一个string的代码片段:

 vector<string> vecstr; vecstr.push_back("abc"); vecstr.push_back("efg"); // etc. string concat = accumulate( vecstr.begin(), vecstr.end(), string("") );