boost::fusion::push_back的正确用法是什么?

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 我都应该创建一个新的向量。)
1个回答

1
(注意:我只是根据 boost::fusion 上过于简略的文档假设每次调用 push_back 时都应该创建一个新向量。)
你并没有创建一个新的向量。`push_back` 返回一个惰性评估的 view|视图,表示扩展序列。如果你想创建一个新的向量,那么可以将 `NewStuff` 定义为。
typedef fusion::vector<Base*, Alpha*, Bravo*, Base*, Alpha*> NewStuff;

你的程序正常工作了。

顺便说一下,融合是一个非常实用的设计。我认为如果你存储实际对象而不是指针,并使用 transform,那就更像融合了。然后 chug 逻辑将被移出类并移到具有适当的每种类型的 operator()struct chug 中。然后就不需要创建新向量,可以使用惰性评估视图。


非常有帮助,谢谢。如果使用实际对象,尤其是不可复制的对象,会有什么好处呢?(不确定Fusion是否会复制)。 - Kyle
至少可以简化内存管理(不需要显式删除,异常安全),并且您不必担心可能的空指针(除非某些值是可选的)。 - Rüdiger Hanke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接