STL容器作为函数中的模板参数,调用错误

Posted

技术标签:

【中文标题】STL容器作为函数中的模板参数,调用错误【英文标题】:STL container as template parameter in function, error in call 【发布时间】:2017-08-09 06:21:50 【问题描述】:

无法理解代码、第二个函数定义或在 main 中调用此函数有什么问题? 我认为,但不确定,调用中的问题,因为没有调用代码编译得很好。编译器 gcc

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template<class T>
void show_element(T ob)

    cout << ob << " ";


template<template<class> class S, class T>
void show_sequence(S<T> sequence)

    for_each(sequence.begin(), sequence.end(), show_element<T>);    


int main(int argc, char const *argv[])

    std::vector<int> v(20, 0);

    //here the problem
    show_sequence<std::vector<int>, int>(v);

    return 0;

【问题讨论】:

algorithms.cpp:在函数'int main(int, const char**)'中:算法.cpp:29:40:错误:没有匹配函数调用'show_sequence(std::vector &)' 算法.cpp:29:40: 注意:候选是:算法.cpp:18:6: 注意:模板 将错误信息添加到问题中。 我建议您从算法函数中获取提示(例如您使用的 std::for_each),并让该函数取而代之的是迭代器。然后,您不仅可以将该函数用于标准容器,还可以用于数组或指针。 我想过这种方法,但这并不是我真正想要的 【参考方案1】:

std::vector 不是一个参数的模板,它也需要一个分配器类型。您可以将其用作vector&lt;T&gt;,因为第二个参数有一个默认值(std::allocator&lt;T&gt;)。

正如它所写的那样,您的模板函数不能接受任何标准容器,因为在我看来,没有一个只需要一个类型参数。

一种可行且不需要您知道容器需要多少模板参数的方法是接受容器类型(不是模板),并从容器类型中收集值类型.

template<class Seq>
void show_sequence(Seq const& sequence)

    typedef typename Seq::value_type T;
    for_each(sequence.begin(), sequence.end(), show_element<T>);    

所有标准容器都有一个value_type 成员,因此这适用于其中任何一个。此外,它适用于任何从标准库中获取线索的容器。

【讨论】:

当你写“std::vector 不是一个参数的模板”时,我必须为模板声明中的任何 stl 容器编写 template 是什么意思? 我知道 Allocator,但这些信息在当前情况下如何帮助我? @Anton - 事实上,如果您接受一个模板,您必须准确指定它需要哪些参数,并且传递的任何模板都必须与这些完全匹配。接受模板(而不是容器类型)将始终限制您可以接受的容器。例如,如果您想显示std::map 怎么办?该容器模板有 4 个参数。其中 3 个您不感兴趣,但您的解决方案必须将它们考虑在内。使用value_type 将使这些考虑消失。 用户 scinart 告诉我我想要什么,但你的变种更好)谢谢你的解释,非常有帮助和有用 哈是的,因为数组采用 std::size_t 模板参数...有一次,我写了一个特征 is_iterable (通过检查 begin() 和 end() 函数)。而不是有一个模板“模板参数”,如果这个类型参数是可迭代的,我只有一个带有检查(通过 SFINAE)的模板参数。它对我的使用来说已经足够好了:)。【参考方案2】:

问题在于std::vector 是一个模板,而std::vector&lt;int&gt; 是一个类型。

当你给函数提供第二个时,你给的是一种类型而不是模板。

因此,您可以将函数重写为:

template<class S>
void show_sequence(S sequence)

此外,vector 不仅采用一个模板参数,而且采用两个(请参阅 StoryTeller 答案)

【讨论】:

【参考方案3】:

类似这个问题:https://***.com/a/29493191/1889040

因为vector是&lt;type, allocator&gt;的模板

代码应该是

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template<class T>
void show_element(T ob)

    cout << ob << " ";

template<template<class,class> class S, class T, class Allocator>
void show_sequence(S<T, Allocator> sequence)

    for_each(sequence.begin(), sequence.end(), show_element<T>);

int main(int argc, char const *argv[])

    std::vector<int> v(20, 0);

    //here problem solved
    show_sequence<vector, int, allocator<int> > (v);
    show_sequence(v);

    return 0;

【讨论】:

以上是关于STL容器作为函数中的模板参数,调用错误的主要内容,如果未能解决你的问题,请参考以下文章

std::enable_if 在模板参数上确定 STL 容器

STL容器自定义内存分配器

STL容器自定义内存分配器

STL容器自定义内存分配器

STL概念

C++--模板&STL