在C聚合类中实现调用多路复用的优雅方式?
发布时间:2020-12-16 03:42:31 所属栏目:百科 来源:网络整理
导读:当多路调用多个子对象时,什么是阻止循环样板代码的优雅方法? 问题描述示例: struct Foo { void Boo(); void Hoo(); bool IsActivated();};struct FooAggregator { ... void Boo(); void Hoo(); ... std::vectorFoo m_foos;};FooAggregator::Boo() { for(si
当多路调用多个子对象时,什么是阻止循环样板代码的优雅方法?
问题描述示例: struct Foo { void Boo(); void Hoo(); bool IsActivated(); }; struct FooAggregator { ... void Boo(); void Hoo(); ... std::vector<Foo> m_foos; }; FooAggregator::Boo() { for(size_t i=0,e=m_foos.size(); i!=e; ++i) { if(m_foos[i].IsActivated()) { m_foos[i].Boo(); } } } FooAggregator::Hoo() { for(size_t i=0,e=m_foos.size(); i!=e; ++i) { if(m_foos[i].IsActivated()) { m_foos[i].Hoo(); } } } 如您所见,FooAggregator实现与单个Foo相同(相似)的接口,迭代调用其各自成员函数的所有Foo对象. 正如您所看到的,迭代循环是完整的样板,为FooAggregator的每个成员函数重复. 从FooAggregators成员函数的实现中删除样板的优雅方法是什么 解决方法
您可以使用Boost.Bind作为@Space_C0wb0y建议.但是如果你出于某种原因不能使用它,那么你可以做这样的事情:
struct FooAggregator { typedef void (Foo::*Fun)(); void Boo() { CallForEach(m_foos.begin(),m_foos.end(),&Foo::Boo); } void Hoo() { CallForEach(m_foos.begin(),&Foo::Hoo); } template<typename FwdIterator> void CallForEach(FwdIterator first,FwdIterator last,Fun fun) { while (first != last ) { if(first->IsActivated()) { (first->*fun)(); } first++; } } }; 或者您可以使用< algorithm>中的std :: for_each如: #include <algorithm> struct FooAggregator { typedef void (Foo::*Fun)(); void Boo() { std::for_each(m_foos.begin(),Call(&Foo::Boo)); } void Hoo() { std::for_each(m_foos.begin(),Call(&Foo::Hoo)); } struct Call { Fun m_fun; Call(Fun fun) : m_fun(fun) {} void operator()(Foo & foo) { if(foo.IsActivated()) { (foo.*m_fun)(); } } }; }; 阅读约Function object以了解第二个例子. 在C 0x(即C 11)中,它非常简单.您可以在std :: for_each中使用lamda: #include <algorithm> struct FooAggregator { void Boo() { std::for_each(m_foos.begin(),[](Foo &foo){ if (foo.IsActivated()) foo.Boo(); } ); } void Hoo() { std::for_each(m_foos.begin(),[](Foo &foo){ if (foo.IsActivated()) foo.Hoo(); } ); } //other code }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |