2010-05-15 38 views
4
// ... snipped includes for iostream and fusion ... 
namespace fusion = boost::fusion; 

class Base 
{ 
protected: int x; 
public: Base() : x(0) {} 
    void chug() { 
     x++; 
     cout << "I'm a base.. x is now " << x << endl; 
    } 
}; 

class Alpha : public Base 
{ 
public: 
    void chug() { 
     x += 2; 
     cout << "Hi, I'm an alpha, x is now " << x << endl; 
    } 
}; 

class Bravo : public Base 
{ 
public: 
    void chug() { 
     x += 3; 
     cout << "Hello, I'm a bravo; x is now " << x << endl; 
    } 
}; 

struct chug { 
    template<typename T> 
    void operator()(T& t) const 
    { 
     t->chug(); 
    } 
}; 

int main() 
{ 
    typedef fusion::vector<Base*, Alpha*, Bravo*, Base*> Stuff; 
    Stuff stuff(new Base, new Alpha, new Bravo, new Base); 

    fusion::for_each(stuff, chug());  // Mutates each element in stuff as expected 

    /* Output: 
     I'm a base.. x is now 1 
     Hi, I'm an alpha, x is now 2 
     Hello, I'm a bravo; x is now 3 
     I'm a base.. x is now 1 
    */ 

    cout << endl; 

    // If I don't put 'const' in front of Stuff... 
    typedef fusion::result_of::push_back<const Stuff, Alpha*>::type NewStuff; 

    // ... then this complains because it wants stuff to be const: 
    NewStuff newStuff = fusion::push_back(stuff, new Alpha); 

    // ... But since stuff is now const, I can no longer mutate its elements :(
    fusion::for_each(newStuff, chug()); 

    return 0; 
}; 

我该如何获得for_each(newStuff,chug())的工作?boost :: fusion :: push_back的正确用法是什么?

(注:我只是从overly brief documentation假设上的boost ::融合,我应该每次我打电话的push_back时间创建一个新的载体)

回答

1

(注:我只是假设从关于boost :: fusion的过度简要文档,我应该在每次调用push_back时创建一个新的向量。)

您并未创建新的向量。 push_back在扩展序列上返回延迟评估的view。如果你想创建一个新的矢量,那么例如typedefNewStuff

typedef fusion::vector<Base*, Alpha*, Bravo*, Base*, Alpha*> NewStuff; 

你的程序则可以。

顺便说一句,融合是一个非常实用的设计。我认为如果你存储实际的对象而不是指针并且使用transform,它会更融合。然后将chug逻辑从类中移出到struct chug,其中每种类型都有合适的operator()。这样就不需要创建新的向量,你可以使用懒惰评估的视图。

+0

非常有帮助,谢谢。如何切换到实际对象会有好处,特别是如果它们不可复制? (不确定融合是否复制)。 – Kyle 2010-05-15 22:53:33

+0

至少,它简化了内存管理(不需要在某处明确地删除,异常安全),并且不必担心可能的NULL指针(除非某些值是可选的)。 – 2010-05-16 11:23:52

相关问题