问题描述
我想编写一个函数,该函数接受具有任何类型的通用容器并进行打印。
让我们先说一下,它不适用于某些关联的容器,并专注于该问题:
template<template<typename> typename Cont,typename T>
void print(const Cont<T>& cont)
{
for (const auto it : cont)
{
cout << it << " ";
}
cout << endl;
}
int main()
{
vector<string> v;
print(v);
}
错误状态:
error C2672: 'print': no matching overloaded function found
error C3207: 'print': invalid template argument for 'Cont',class template expected
任何人都可以在这里解释为什么编译器无法推断类型吗?
即使我明确声明了print<vector<string>>(v)
?
解决方法
std::vector
有多个类模板参数。
template<
class T,// -----------> you have mentioned!
class Allocator = std::allocator<T> // -----> this didn't!
> class vector;
但是您只提供了一个。这就是没有匹配的重载编译器错误的原因。
为了解决此问题,您需要在模板模板arg中提供可变参数。
template<template<typename...> typename Cont,typename T>
// ^^^^^^^^^^^^^^^^^^^^
void print(const Cont<T>& cont)
{
for (const auto& it : cont) {
std::cout << it << " ";
}
std::cout << std::endl;
}
但是,您可以简单地做到这一点
template <typename Cont>
void print(const Cont& cont)
{
// ...
}
或者像标准方式一样,传递the begin and end iterator of the container to the function
#include <algorithm> // std::copy
#include <iterator> // std::iterator_traits
template<typename Iterator>
constexpr void print(const Iterator begin,const Iterator end) noexcept
{
using ValueType = typename std::iterator_traits<Iterator>::value_type;
std::copy(begin,end,std::ostream_iterator<ValueType>(std::cout," "));
std::cout << "\n";
}
并称呼它
print(v.begin(),v.end());
,
std::vector
定义为
template<
class T,class Allocator = std::allocator<T>
> class vector;
std::vector
是具有两个模板参数的类模板。不匹配
您的函数的template template参数。
更改为
template <typename Cont>
void print(const Cont& cont)
{
for (const auto& elem : cont) {
std::cout << elem << " ";
}
std::cout << std::endl;
}
如有必要,您可以从容器中推断出T
。