代码之家  ›  专栏  ›  技术社区  ›  justinhj

可以使用C++模板指定集合类型和该类型的专业化吗?

  •  3
  • justinhj  · 技术社区  · 16 年前

    例如,我想专门化一个类,让它有一个成员变量,它是一个STL容器,比如说一个向量或一个列表,所以我需要如下的东西:

    template <class CollectionType, class ItemType>
    class Test
    {
    public:
        CollectionType<ItemType> m_collection;
    };
    

    所以我可以做到:

    Test  t = Test<vector, int>();
    t.m_collection<vector<int>> = vector<int>();
    

    但这会产生

    test.cpp:12: error: `CollectionType' is not a template
    
    3 回复  |  直到 15 年前
        1
  •  9
  •   Greg Rogers    16 年前

    为什么不这样做?

    template <class CollectionType>
    class Test
    {
    public:
        CollectionType m_collection;
    };
    
    Test  t = Test<vector<int> >();
    t.m_collection = vector<int>();
    

    如果需要项类型,可以使用 CollectionType::value_type .

    编辑:对于创建返回值类型的成员函数的问题,可以这样做:

    typename CollectionType::value_type foo();
    

    添加类型名是因为CollectionType尚未绑定到实际类型。所以没有可以查找的值类型。

        2
  •  13
  •   Luc Touraille    15 年前

    您需要的是模板模板参数:

    template <template <typename> class CollectionType, class ItemType>
    class Test
    {
    public:
        CollectionType<ItemType> m_collection;
    };
    

    我们在这里所做的是指定第一个模板参数,即 CollectionType ,是类型模板。因此, Test 只能用本身是模板的类型来实例化。

    但是,正如@binary worrier在注释中指出的那样,这对STL容器不起作用,因为它们 模板参数:一个用于元素类型,另一个用于管理存储分配的分配器类型(具有默认值)。

    因此,需要更改第一个模板参数,使其具有两个参数:

    template <template <typename,typename> class CollectionType, class ItemType>
    class Test
    {
    public:
        CollectionType<ItemType> m_collection;
    };
    

    等等,那也不行!的确, 集合类型 等待另一个参数,分配器…现在您有两个解决方案:

    1。强制使用特定的分配器:

    CollectionType<ItemType, std::allocator<ItemType> > m_collection
    

    2。将分配器的模板参数添加到类中:

    template <template <typename,typename> class CollectionType, 
              class ItemType,
              class Allocator = std::allocator<ItemType> >
    class Test
    {
    public:
        CollectionType<ItemType, Allocator> m_collection;
    };
    

    所以,正如您所看到的,您最终得到的是一些相当复杂的东西,这似乎真的扭曲处理STL容器…

    我的建议:请参阅格雷格·罗杰斯的回答,了解更好的方法:)!

        3
  •  2
  •   tragomaskhalos    16 年前

    科莫在线喜欢这样:

    #include <vector>
    
    template <template <class T, class A = std::allocator<T> > class CollectionType, class ItemType>
    class Test
    {
    public:
        CollectionType<ItemType> m_collection;
    };
    
    void foo()
    {
    using std::vector;
    Test<vector,int>  t = Test<vector, int>();
    t.m_collection = vector<int>();
    }