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

发布于 2024-11-30 11:01:09 字数 653 浏览 0 评论 0原文

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

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

这是怎么回事?

我怎样才能让这个函数返回正确的类型?

I am trying to write a function which can take any of the standard containers(list, stack, vector etc) as it's arguments. I also wish to know the type that is within the container. Here is what I have tried.

#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);
}

The type of container_type once inside this function is always _Container_base_aux_alloc_empty which(I think) is a base class of the standard containers.

What is going on here?

How would I make this function return the correct type?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

内心荒芜 2024-12-07 11:01:09

container_type 的 typeid 没有用,因为那只是一个模板类,而模板类根本不是真正的类型,只有实例化后才变成一个类型。因此,您真正想要的是值类型的 data_type 类型,以及实例化容器类型的 container_type 类型。当然,更好的是采用 container_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());
}

The typeid of container_type is no use, because that's just a template class, and a template class isn't a real type at all, it only becomes one after instantiation. So what you really want is the type of data_type for the value type, and the type of container_type<data_type> for the type of the instantiated container. Even better, of course, is to take container_type<data_type>::value_type as the value type.

Note that most containers take more than one template parameter, so you'd be better off writing this with variadic templates:

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());
}
老街孤人 2024-12-07 11:01:09

你的代码将无法工作,因为一旦有人交换了分配器或类似的东西,那么你就完了。如果在 C++03 中,您应该采用任何 T 并使用 ::value_type,或者在 C++0x 中使用类型推导。

此外, .name() 根本没有定义为返回任何有用的内容。在任何情况下。实现可以为每种类型返回“哈哈傻瓜!使用此语言功能祝你好运”并保持一致。

Your code won't work, because as soon as someone swaps out the allocator or something like that, then you're done for. You should take any T and use ::value_type, if in C++03, or type deduction in C++0x.

Also, .name() isn't defined to return anything useful, at all. In any situation. An implementation could return "har har sucker! good luck using this language feature" for every type and be conforming.

谜兔 2024-12-07 11:01:09

我不太相信 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)

I would not trust the output of typeid() that much. type_info::Name is not guaranteed to return some unique identfier. So it might very well be the type inside the function is what you expect.

The best way to get some kind of name for the type is to use a macro, something like this:

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)
悲欢浪云 2024-12-07 11:01:09

您已经知道了容器的类型。它是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 并避免这种混淆。

You already have the type of the container. It's data_type. Just use it like this. If in doubt you can also use typename container_type::value_type which is a typedef for the template argument of the container.

So much for using types. Returning a type is something entirely different in C++ and is generally considered a part of template meta-programming.

This, rather pointless snippet, extracts the value_type from some type T.

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

But you might as well use the value_type directly and avoid this piece of obfuscation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文