可变参数模板化容器传递对包含项的引用

Variadic templated container passing reference to contained items

我正在尝试创建一个可变参数模板容器,它将包含引用回容器的项目。不幸的是,我不太清楚如何声明容器。 这有点像先有鸡还是先有蛋的问题。 Items 在 Container 上模板化,但 Container 也在 Items 上模板化。

我试图提炼出下面的相关代码。它抱怨未声明“CollectionA”。

我怎样才能使这个工作?

#include <tuple>

template <typename CollectionT, typename Derived>
class ItemBase
{
public:
    ItemBase(CollectionT& c) : collection(c) {}

protected:
    CollectionT& collection;
};

template <typename CollectionT>
class ItemA : public ItemBase<CollectionT, ItemA<CollectionT> > {
    void aMethod() {
        this->collection.doSomething();
    }
};

template <typename CollectionT>
class ItemB : public ItemBase<CollectionT, ItemB<CollectionT> > {

};

template <typename ...Items>
class Collection
{
public:
    Collection() : items(*this) {}

    std::tuple<Items...> items;

    void doSomething() {}
};

int main( int, char** )
{
    // The Items are templated on the Collection, so how do I specify them?
    using CollectionA = Collection<ItemA<CollectionA>, ItemB<CollectionA>>;
    CollectionA collection;
}

这应该可以完成工作。

#include <tuple>

class CollectionBase
{
public:
    void doSomething() {}
};

class ItemBase
{
public:
    ItemBase(CollectionBase& c) : collection(c) {}

protected:
    CollectionBase& collection;
};

template <typename ...Items>
class Collection : CollectionBase
{
public:
    Collection() : items{Items{*this}...} {}

    std::tuple<Items...> items;
};

template <typename T>
class Item : ItemBase
{
public:
    Item(CollectionBase& c) : ItemBase(c) {}

    void doSomething()
    {
        collection.doSomething();
    }
};

int main( int, char** )
{
    Collection<Item<int>, Item<char>> collection;
}

如果您确认所有 Items 都将 CollectionA 本身作为模板参数,为什么不传递模板?

template <template<typename>class... ItemTempls>
class Collection{
public:
    Collection() : items(*this) {}

    std::tuple<ItemTempls<Collection>...> items;

    void doSomething() {}
};

int main( int, char** ){
    using CollectionA = Collection<ItemA, ItemB>;
    CollectionA collection;
}

和CRTP类似,template模板参数总是用来解决递归声明的问题