Templates and STL

前端 未结 6 1775
情歌与酒
情歌与酒 2021-01-05 18:31

The following code represents a container based on std::vector

template 
struct TList
{
    typedef std::vector  Type;
};


         


        
6条回答
  •  难免孤独
    2021-01-05 18:36

    Yes, but not directly:

    template  class Container>
    struct TList
    {
        typedef typename Container::type type;
    };
    

    Then you can define different container policies:

    template 
    struct vector_container
    {
        typedef std::vector type;
    };
    
    template 
    struct map_container
    {
        typedef std::map type;
    };
    
    TList v;
    TList m;
    

    A bit verbose, though.* To do things directly, you'd need to take the route described by James, but as he notes this is ultimately very inflexible.

    However, with C++0x we can do this just fine:

    #include 
    #include 
    
    template  class Container, typename... Args> 
    struct TList
    {
        // Args lets the user specify additional explicit template arguments
        Container storage;
    };
    
    int main()
    {
        TList v;
        TList m;
    }
    

    Perfect. Unfortunately there's no way to reproduce this in C++03, except via the indirection policy classes introduce as described above.


    *I want to emphasize that by "A bit verbose" I mean "this is unorthodox". The correct solution for your problem is what the standard library does, as Jerry explains. You just let the user of your container adapter specify the entire container type directly:

    template >
    struct TList
    {};
    

    But this leaves a big problem: what if I don't want the value type of the container to be Item but something_else? In other words, how can I change the value type of an existing container to something else? In your case you don't, so read no further, but in the case we do, we want to rebind a container.

    Unfortunately for us, the containers don't have this functionality, though allocators do:

    template 
    struct allocator
    {
        template 
        struct rebind
        {
            typedef allocator type;
        };
    
        // ...
    };
    

    This allows us to get an allocator given an allocator. How can we do the same for containers without this intrusive utility? In C++0x, it's easy:

    template 
    struct rebind; // not defined
    
    template 
    struct rebind>
    {
        // assumes the rest are filled with defaults**
        typedef Container type; 
    };
    

    Given std::vector, we can perform rebind>::type, for example. Unlike the previous C++0x solution, this one can be emulated in C++03 with macros and iteration..


    **Note this mechanism can be made much more powerful, like specifying which arguments to keep, which to rebind, which to rebind themselves before using as arguments, etc., but that's left as an exercise for the reader. :)

提交回复
热议问题