模板和STL [英] Templates and STL

查看:189
本文介绍了模板和STL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码表示基于std :: vector的容器

 模板< typename Item> 
struct TList
{
typedef std :: vector< Item>类型;
};


template< typename Item>
class List
{
private
typename TList< Item> :: Type items;
....
}

int main()
{
List< Object>列表;
}

可以模板化std :: vector并创建一个通用容器

 模板< typename Item,typename stl_container> 
struct TList
{
typedef stl_container< Item> ;;
};

其中stl_container表示std :: vector,std :: list,std :: set ...?我想在创建时选择容器的类型。

  List< Object,std :: vector>列表; //对象的向量,而不是真正的代码
List< Object,std :: vector>列表; //对象列表,不是真正的代码

感谢您的回答...



更新的问题:



我尝试了以下代码,但存在错误:

  #include< vector> 
template< typename Item,typename Container>
struct TList
{
typedef typename Container< Item> :: type type; //错误C2059:语法错误:'<',错误C2238:意外的令牌之前';
};


template< typename T>
struct vector_container
{
typedef std :: vector< T>类型;
};

int _tmain(int argc,_TCHAR * argv [])
{
TList< int,vector_container> v;
TList< int,map_container> m;
}


解决方案

  template< typename Item,template< typename> class Container> 
struct TList
{
typedef typename Container< Item> :: type type;
};然后您可以定义不同的容器策略:

pre> template< typename T>
struct vector_container
{
typedef std :: vector< T>类型;
};

template< typename T>
struct map_container
{
typedef std :: map< T,std :: string>类型;
};

TList< int,vector_container> v;
TList< int,map_container> m;

有点冗长。*要直接做事,你需要< =http://stackoverflow.com/questions/4962518/templates-and-stl/4962623#4962623> James描述的路线,但他指出,这最终非常不灵活。



但是,对于C ++ 0x,我们可以这样做:

  #include < map> 
#include< vector>

template< typename Item,
template< typename ...> class Container,typename ... Args>
struct TList
{
// Args允许用户指定额外的显式模板参数
Container< Item,Args ...>存储;
};

int main()
{
TList< int,std :: vector> v;
TList< int,std :: map,float> m;
}

完美。不幸的是,除非通过如上所述的间接策略类引入,否则没有办法在C ++ 03中重现。






*我要强调的是,有点冗长我的意思是这是非正统的。您的问题的正确解决方案是标准库的作用, Jerry解释。您只需让容器适配器的用户直接指定整个容器类型:

  template< typename Item,typename Container = std :: vector< Item>> 
struct TList
{};

但这留下一个大问题:如果我不想容器的值类型 something_else< Item> ?换句话说,如何将现有容器的值类型更改为其他值?在你的情况下你不这样做,所以不要再读了,但在我们这样做的情况下,我们要重新绑定一个容器。



对于我们来说,容器没有这个功能,虽然分配器做:

  template< typename T& 
struct allocator
{
template< typename U>
struct rebind
{
typedef allocator< U>类型;
};

// ...
};

这允许我们获得 allocator< U> 给出分配器< T> 。我们如何可以做同样的容器没有这个侵入的实用程序?在C ++ 0x中,很容易:

  template< typename T,typename Container> 
struct rebind; //未定义

模板< typename T,typename Container,typename ... Args>
struct rebind< T,Container< Args ...>>
{
//假设其余都填充默认值**
typedef Container< T>类型;
};

给定 std :: vector< int> ,我们可以执行 rebind< float,std :: vector< int>> :: type 。与以前的C ++ 0x解决方案不同,这个可以在C ++ 03中用宏和迭代来模拟。






**注意,这种机制可以做得更强大,比如指定保留哪些参数,重新绑定哪些参数,在作为参数使用之前重新绑定自身,等等,但这只是一个练习。 :)


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

template <typename Item>
struct TList
{
    typedef std::vector <Item> Type;
};


template <typename Item>
class List
{
private
            typename TList <Item>::Type items;
    ....
}

int main()
{
  List <Object> list;
}

Is it possible to templatize std::vector and create a general container, something like that?

template <typename Item, typename stl_container>
struct TList
{
    typedef stl_container<Item>;
};

where stl_container represents std::vector, std::list, std::set...? I would like to choose the type of container at the time of the creation.

List <Object, std::vector> list; //vector of objects, not a real code
List <Object, std::vector> list; //list of objects, not a real code

Thanks for your answers...

Updated question:

I tried the following code but there are errors:

#include <vector>
template <typename Item, typename Container>
struct TList
{
   typedef typename Container <Item>::type type; //Error C2059: syntax error : '<', Error C2238: unexpected token(s) preceding ';
};


template <typename T>
struct vector_container
{
  typedef std::vector<T> type;
};

int _tmain(int argc, _TCHAR* argv[])
{
TList <int, vector_container> v;
TList <int, map_container> m;
}

解决方案

Yes, but not directly:

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

Then you can define different container policies:

template <typename T>
struct vector_container
{
    typedef std::vector<T> type;
};

template <typename T>
struct map_container
{
    typedef std::map<T, std::string> type;
};

TList<int, vector_container> v;
TList<int, map_container> 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 <map>
#include <vector>

template <typename Item,
            template <typename...> class Container, typename... Args> 
struct TList
{
    // Args lets the user specify additional explicit template arguments
    Container<Item, Args...> storage;
};

int main()
{
    TList<int, std::vector> v;
    TList<int, std::map, float> 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 <typename Item, typename Container = std::vector<Item>>
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<Item>? 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 <typename T>
struct allocator
{
    template <typename U>
    struct rebind
    {
        typedef allocator<U> type;
    };

    // ...
};

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

template <typename T, typename Container>
struct rebind; // not defined

template <typename T, typename Container, typename... Args>
struct rebind<T, Container<Args...>>
{
    // assumes the rest are filled with defaults**
    typedef Container<T> type; 
};

Given std::vector<int>, we can perform rebind<float, std::vector<int>>::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. :)

这篇关于模板和STL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆