模板模板C ++函数

时间:2011-09-26 12:55:23

标签: c++ templates std

如何编写在任意类型的任意容器上运行的模板函数?例如,我如何概括这个虚拟函数

template <typename Element>
void print_size(const std::vector<Element> & a)
{
    cout << a.size() << endl;
}

template <template<typename> class Container, typename Element>
void print_size(const Container<Element> & a)
{
    cout << a.size() << endl;
}

以下是典型用法

std::vector<std::string> f;
print_size(f)

这给出了错误

tests/t_distances.cpp:110:12: error: no matching function for call to ‘print(std::vector<std::basic_string<char> >&)’. I'm guessing I must tell the compiler something more specific about what types that are allowed.

调用模板使用变体是什么?如何解决?

5 个答案:

答案 0 :(得分:13)

您是否有特定原因使用模板模板?为什么不这样呢?

template <typename Container>
void print_size(Container const& a)
{
    cout << a.size() << endl;
}

通常,模板模板不值得麻烦。在你的特定情况下,肯定没有用它们,如果你真的需要访问成员类型,我建议你屈服于常规练习并使用元函数(在这种情况下为typename Container::value_type)。

答案 1 :(得分:3)

问题是vector模板有两个类型参数,而模板只接受接受单个参数的模板参数。最简单的解决方案是提升类型安全性并仅使用Container作为类型:

template <typename Container>
void print_size( Container const & c ) {
   std::cout << c.size() << std::endl;
}

可能添加静态检查(无论类型Container是什么,它必须具有value_type嵌套类型Element ...)替代方法是创建模板模板参数匹配要传递的模板(包括用于关联容器的序列,分配器和顺序谓词的分配器)...

答案 2 :(得分:3)

我知道很久以前就问过这个问题了,但我遇到了同样的问题,解决方法是你需要写

template <template <typename,typename> class Container, typename element, typename Allocator>
void print_size(Container<element, Allocator> & a)
{
    std::cout << a.size() << std::endl;
}

因为矢量有两个模板参数

答案 3 :(得分:2)

为什么要使用像

这样的东西
template <template<typename> class Container, typename Element>
void print_size(const Container<Element> & a)
{
    cout << a.size() << endl;
}

?以更简单的方式使用它:

template<typename Container>
void print_size(const Container & a)
{
    cout << a.size() << endl;
}

致电print_size(f)时,您会在print_size Container时致电vector<string>

答案 4 :(得分:-1)

对于这些类型的泛型算法,我总是喜欢迭代器,即

template <typename IteratorType>
void print_size(IteratorType begin, IteratorType end) {
   std::cout << std::distance(begin, end) << std::endl;
}

致电:

std::vector<std::string> f;
print_size(f.begin(), f.end());