带有模板化参数的C ++函数模板

时间:2011-08-21 18:43:43

标签: c++ templates template-function

我正在尝试编写一个函数,它可以将任何标准容器(列表,堆栈,向量等)作为它的参数。我也想知道容器内的类型。这是我尝试过的。

#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,我认为它是标准容器的基类。

这里发生了什么?

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

4 个答案:

答案 0 :(得分: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());
}

答案 1 :(得分:1)

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

获取该类型的某种名称的最佳方法是使用宏,如下所示:

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)

答案 2 :(得分:1)

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

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

这个相当无意义的摘录从某些类型value_type中提取T

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

但你也可以直接使用value_type并避免这种混淆。

答案 3 :(得分:1)

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

此外,.name()未定义为返回任何有用的内容。在任何情况下。对于每种类型而言,实现可以返回“har har sucker!使用此语言功能的好运”并且符合要求。