2011-08-21 153 views
2

我想写一个函数,它可以接受任何标准容器(列表,堆栈,向量等)作为参数。我也希望知道容器内的类型。这是我尝试过的。带有模板化参数的C++函数模板

#include<iostream> 
#include<list> 
#include<vector> 

template<class data_type, template<class> class container_type> 
void type(container_type<data_type>& _container){ 
     std::cout<<typeid(container_type).name()<<std::endl; 
} 


int main(){ 

    std::list<int> list_t; 
    std::vector<int> vector_t; 
    type(list_t); 
    type(vector_t); 
} 

一旦此功能内的类型的container_type总是_Container_base_aux_alloc_empty其中(我认为)是一个基类的标准容器。

这是怎么回事?

我该如何让这个函数返回正确的类型?

回答

1

你的代码不会工作,因为只要有人将分配器或类似的东西换掉,那么你就完成了。如果在C++ 03中,您应该使用任何T并使用::value_type,或者在C++ 0x中输入扣减。

而且,.name()没有被定义为返回任何有用的东西。在任何情况下。一个实现可以为每种类型返回“har har sucker!祝你好运使用这种语言功能”并且符合要求。

1

我不会信任typeid()的输出。 type_info :: Name不保证返回一些唯一标识符。所以它很可能是函数内部的类型就是你所期望的。

得到某种名称类型的最好的办法是使用宏,这样的事情:

template<class data_type, template<class> class container_type> 
void type_helper(container_type<data_type>& _container, const char* charStr){ 
     std::cout<< charStr << std::endl 
} 

#define type(container) type_helper(container, #container) 
1

您已经拥有了容器的类型。这是data_type。就这样使用它。如果有疑问,您还可以使用typename container_type::value_type这是一个typedef用于容器的模板参数。

这么多使用类型。返回类型在C++中完全不同,通常被认为是模板元编程的一部分。

这个,而不是毫无意义的代码片段,从T中提取value_type

template<typename T> 
struct inner_type { 
    typedef T::value_type value_type; 
}; 

但你还不如直接使用value_type,避免这块混淆。

2

container_type的typeid是没有用的,因为这只是一个模板类,而模板类根本就不是真正的类型,它只在实例化后才变成一个。因此,您真正需要的是值类型data_type的类型,以及实例化容器类型的container_type<data_type>类型。当然,更好的做法是将container_type<data_type>::value_type作为值类型。

注意,大多数容器需要超过一个模板参数,所以你会更好用可变参数模板写的:

template <template <typename...> class Container, typename ...Args> 
void print_type(const Container<Args...> &) 
{ 
    typedef typename Container<Args...>::value_type value_type; 
    print(typeid(Container<Args...>).name()); 
    print(typeid(value_type).name()); 
}